From ae8de0e7a29b870d362d6c1017096639856b263c Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 24 May 2021 08:24:51 -0700 Subject: [PATCH] REF: share __array_wrap__ --- pandas/core/indexes/base.py | 1 + pandas/core/indexes/datetimelike.py | 14 ++++------- pandas/core/indexes/datetimes.py | 4 ++-- pandas/core/indexes/interval.py | 8 ++----- pandas/core/indexes/period.py | 37 ----------------------------- 5 files changed, 9 insertions(+), 55 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 8fb88e625d948..33f31c4ce96c0 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -813,6 +813,7 @@ def __array_wrap__(self, result, context=None): return result attrs = self._get_attributes_dict() + attrs.pop("freq", None) # For DatetimeIndex/TimedeltaIndex return Index(result, **attrs) @cache_readonly diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index b2377f5b27966..185f1dced72bf 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -35,7 +35,6 @@ ) from pandas.core.dtypes.common import ( - is_bool_dtype, is_categorical_dtype, is_dtype_equal, is_integer, @@ -113,15 +112,10 @@ def __array_wrap__(self, result, context=None): """ Gets called after a ufunc and other functions. """ - result = lib.item_from_zerodim(result) - if is_bool_dtype(result) or lib.is_scalar(result): - return result - - attrs = self._get_attributes_dict() - if not is_period_dtype(self.dtype) and attrs["freq"]: - # no need to infer if freq is None - attrs["freq"] = "infer" - return type(self)(result, **attrs) + out = super().__array_wrap__(result, context=context) + if isinstance(out, DatetimeTimedeltaMixin) and self.freq is not None: + out = out._with_freq("infer") + return out # ------------------------------------------------------------------------ diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index ac09159c23566..d02f415a4f29f 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -257,8 +257,8 @@ class DatetimeIndex(DatetimeTimedeltaMixin): _engine_type = libindex.DatetimeEngine _supports_partial_string_indexing = True - _comparables = ["name", "freqstr", "tz"] - _attributes = ["name", "tz", "freq"] + _comparables = ["name", "freqstr"] + _attributes = ["name", "freq"] _is_numeric_dtype = False diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index fc92a1b3afe53..1dfcb0ec29f27 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -256,7 +256,7 @@ def func(self, other, sort=None): class IntervalIndex(ExtensionIndex): _typ = "intervalindex" _comparables = ["name"] - _attributes = ["name", "closed"] + _attributes = ["name"] # annotate properties pinned via inherit_names closed: str @@ -422,12 +422,8 @@ def __contains__(self, key: Any) -> bool: def _multiindex(self) -> MultiIndex: return MultiIndex.from_arrays([self.left, self.right], names=["left", "right"]) - def __array_wrap__(self, result, context=None): - # we don't want the superclass implementation - return result - def __reduce__(self): - d = {"left": self.left, "right": self.right} + d = {"left": self.left, "right": self.right, "closed": self.closed} d.update(self._get_attributes_dict()) return _new_IntervalIndex, (type(self), d), None diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index 136843938b683..2f2d16b01af53 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -34,7 +34,6 @@ from pandas.util._decorators import doc from pandas.core.dtypes.common import ( - is_bool_dtype, is_datetime64_any_dtype, is_float, is_integer, @@ -350,42 +349,6 @@ def __contains__(self, key: Any) -> bool: # ------------------------------------------------------------------------ # Index Methods - def __array_wrap__(self, result, context=None): - """ - Gets called after a ufunc and other functions. - - Needs additional handling as PeriodIndex stores internal data as int - dtype - - Replace this to __numpy_ufunc__ in future version and implement - __array_function__ for Indexes - """ - if isinstance(context, tuple) and len(context) > 0: - func = context[0] - if func is np.add: - pass - elif func is np.subtract: - name = self.name - left = context[1][0] - right = context[1][1] - if isinstance(left, PeriodIndex) and isinstance(right, PeriodIndex): - name = left.name if left.name == right.name else None - return Index(result, name=name) - elif isinstance(left, Period) or isinstance(right, Period): - return Index(result, name=name) - elif isinstance(func, np.ufunc): - if "M->M" not in func.types: - msg = f"ufunc '{func.__name__}' not supported for the PeriodIndex" - # This should be TypeError, but TypeError cannot be raised - # from here because numpy catches. - raise ValueError(msg) - - if is_bool_dtype(result): - return result - # the result is object dtype array of Period - # cannot pass _simple_new as it is - return type(self)(result, freq=self.freq, name=self.name) - def asof_locs(self, where: Index, mask: np.ndarray) -> np.ndarray: """ where : array of timestamps