From f7247d274b47bb28ae71a8870d0c0e8e603ead53 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 1 Jan 2020 14:09:24 -0800 Subject: [PATCH 1/2] REF: delegate more methods for DTA/TDA --- pandas/core/indexes/datetimes.py | 33 ++++++------------------------- pandas/core/indexes/period.py | 19 +++++------------- pandas/core/indexes/timedeltas.py | 23 ++++++++------------- 3 files changed, 19 insertions(+), 56 deletions(-) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index f8e8a7037b9c4..a86b0d883b081 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -66,8 +66,12 @@ class DatetimeDelegateMixin(DatetimelikeDelegateMixin): # We also have a few "extra" attrs, which may or may not be raw, # which we we dont' want to expose in the .dt accessor. _extra_methods = ["to_period", "to_perioddelta", "to_julian_date", "strftime"] - _extra_raw_methods = ["to_pydatetime", "_local_timestamps", "_has_same_tz"] - _extra_raw_properties = ["_box_func", "tz", "tzinfo"] + _extra_raw_methods = [ + "to_pydatetime", + "_local_timestamps", + "_has_same_tz", + ] + _extra_raw_properties = ["_box_func", "tz", "tzinfo", "dtype"] _delegated_properties = DatetimeArray._datetimelike_ops + _extra_raw_properties _delegated_methods = ( DatetimeArray._datetimelike_methods + _extra_methods + _extra_raw_methods @@ -197,8 +201,6 @@ class DatetimeIndex(DatetimeTimedeltaMixin, DatetimeDelegateMixin): _engine_type = libindex.DatetimeEngine _supports_partial_string_indexing = True - _tz = None - _freq = None _comparables = ["name", "freqstr", "tz"] _attributes = ["name", "tz", "freq"] @@ -310,25 +312,6 @@ def __array__(self, dtype=None): dtype = "M8[ns]" return np.asarray(self._data, dtype=dtype) - @property - def dtype(self): - return self._data.dtype - - @property - def tz(self): - # GH 18595 - return self._data.tz - - @tz.setter - def tz(self, value): - # GH 3746: Prevent localizing or converting the index by setting tz - raise AttributeError( - "Cannot directly set timezone. Use tz_localize() " - "or tz_convert() as appropriate" - ) - - tzinfo = tz - @cache_readonly def _is_dates_only(self) -> bool: """ @@ -999,10 +982,6 @@ def __getitem__(self, key): return result return type(self)(result, name=self.name) - @property - def _box_func(self): - return lambda x: Timestamp(x, tz=self.tz) - # -------------------------------------------------------------------- @Substitution(klass="DatetimeIndex") diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index 0cd4b4d4bca8d..022e3ba674a27 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -66,12 +66,11 @@ class PeriodDelegateMixin(DatetimelikeDelegateMixin): """ _delegate_class = PeriodArray - _delegated_properties = PeriodArray._datetimelike_ops - _delegated_methods = set(PeriodArray._datetimelike_methods) | { - "_addsub_int_array", - "strftime", - } - _raw_properties = {"is_leap_year"} + _raw_methods = {"_format_native_types"} + _raw_properties = {"is_leap_year", "freq"} + + _delegated_properties = PeriodArray._datetimelike_ops + list(_raw_properties) + _delegated_methods = set(PeriodArray._datetimelike_methods) | _raw_methods @delegate_names(PeriodArray, PeriodDelegateMixin._delegated_properties, typ="property") @@ -262,10 +261,6 @@ def _simple_new(cls, values, name=None, freq=None, **kwargs): def values(self): return np.asarray(self) - @property - def freq(self) -> DateOffset: - return self._data.freq - def _shallow_copy(self, values=None, **kwargs): # TODO: simplify, figure out type of values if values is None: @@ -363,10 +358,6 @@ def _maybe_convert_timedelta(self, other): # ------------------------------------------------------------------------ # Rendering Methods - def _format_native_types(self, na_rep="NaT", quoting=None, **kwargs): - # just dispatch, return ndarray - return self._data._format_native_types(na_rep=na_rep, quoting=quoting, **kwargs) - def _mpl_repr(self): # how to represent ourselves to matplotlib return self.astype(object).values diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index 8dd8bd8642354..07f6cf160d7c3 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -41,19 +41,16 @@ class TimedeltaDelegateMixin(DatetimelikeDelegateMixin): # We also have a few "extra" attrs, which may or may not be raw, # which we don't want to expose in the .dt accessor. _delegate_class = TimedeltaArray - _delegated_properties = TimedeltaArray._datetimelike_ops + ["components"] - _delegated_methods = TimedeltaArray._datetimelike_methods + [ - "_box_values", - "__neg__", - "__pos__", - "__abs__", - "sum", - "std", - "median", - ] - _raw_properties = {"components"} + _raw_properties = {"components", "_box_func"} _raw_methods = {"to_pytimedelta", "sum", "std", "median"} + _delegated_properties = TimedeltaArray._datetimelike_ops + list(_raw_properties) + _delegated_methods = ( + TimedeltaArray._datetimelike_methods + + list(_raw_methods) + + ["_box_values", "__neg__", "__pos__", "__abs__"] + ) + @delegate_names( TimedeltaArray, TimedeltaDelegateMixin._delegated_properties, typ="property" @@ -237,10 +234,6 @@ def _format_native_types(self, na_rep="NaT", date_format=None, **kwargs): # ------------------------------------------------------------------- # Wrapping TimedeltaArray - @property - def _box_func(self): - return lambda x: Timedelta(x, unit="ns") - def __getitem__(self, key): result = self._data.__getitem__(key) if is_scalar(result): From c8d6b592acb0539fa714bde6c12dfa2dab2c7ebe Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 1 Jan 2020 15:33:40 -0800 Subject: [PATCH 2/2] delegate _format_native_types --- pandas/core/arrays/timedeltas.py | 2 +- pandas/core/indexes/datetimes.py | 17 ++++++----------- pandas/core/indexes/timedeltas.py | 11 +---------- 3 files changed, 8 insertions(+), 22 deletions(-) diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 11f4131df62a6..87a76b8681da4 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -445,7 +445,7 @@ def _formatter(self, boxed=False): return _get_format_timedelta64(self, box=True) - def _format_native_types(self, na_rep="NaT", date_format=None): + def _format_native_types(self, na_rep="NaT", date_format=None, **kwargs): from pandas.io.formats.format import _get_format_timedelta64 formatter = _get_format_timedelta64(self._data, na_rep) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index a86b0d883b081..f6f46d7e66c69 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -1,5 +1,6 @@ -from datetime import datetime, time, timedelta +from datetime import datetime, time, timedelta, tzinfo import operator +from typing import Optional import warnings import numpy as np @@ -70,6 +71,7 @@ class DatetimeDelegateMixin(DatetimelikeDelegateMixin): "to_pydatetime", "_local_timestamps", "_has_same_tz", + "_format_native_types", ] _extra_raw_properties = ["_box_func", "tz", "tzinfo", "dtype"] _delegated_properties = DatetimeArray._datetimelike_ops + _extra_raw_properties @@ -92,7 +94,7 @@ class DatetimeDelegateMixin(DatetimelikeDelegateMixin): DatetimeArray, DatetimeDelegateMixin._delegated_methods, typ="method", - overwrite=False, + overwrite=True, ) class DatetimeIndex(DatetimeTimedeltaMixin, DatetimeDelegateMixin): """ @@ -216,6 +218,8 @@ class DatetimeIndex(DatetimeTimedeltaMixin, DatetimeDelegateMixin): _datetimelike_ops = DatetimeArray._datetimelike_ops _datetimelike_methods = DatetimeArray._datetimelike_methods + tz: Optional[tzinfo] + # -------------------------------------------------------------------- # Constructors @@ -384,15 +388,6 @@ def _mpl_repr(self): # how to represent ourselves to matplotlib return libts.ints_to_pydatetime(self.asi8, self.tz) - def _format_native_types(self, na_rep="NaT", date_format=None, **kwargs): - from pandas.io.formats.format import _get_format_datetime64_from_values - - fmt = _get_format_datetime64_from_values(self, date_format) - - return libts.format_array_from_datetime( - self.asi8, tz=self.tz, format=fmt, na_rep=na_rep - ) - @property def _formatter_func(self): from pandas.io.formats.format import _get_format_datetime64 diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index 07f6cf160d7c3..795b4836b9a2a 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -42,7 +42,7 @@ class TimedeltaDelegateMixin(DatetimelikeDelegateMixin): # which we don't want to expose in the .dt accessor. _delegate_class = TimedeltaArray _raw_properties = {"components", "_box_func"} - _raw_methods = {"to_pytimedelta", "sum", "std", "median"} + _raw_methods = {"to_pytimedelta", "sum", "std", "median", "_format_native_types"} _delegated_properties = TimedeltaArray._datetimelike_ops + list(_raw_properties) _delegated_methods = ( @@ -222,15 +222,6 @@ def _formatter_func(self): return _get_format_timedelta64(self, box=True) - def _format_native_types(self, na_rep="NaT", date_format=None, **kwargs): - from pandas.io.formats.format import Timedelta64Formatter - - return np.asarray( - Timedelta64Formatter( - values=self, nat_rep=na_rep, justify="all" - ).get_result() - ) - # ------------------------------------------------------------------- # Wrapping TimedeltaArray