diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 6899e47045c1c..3609c68a26c0f 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -776,12 +776,14 @@ def __rdivmod__(self, other): res2 = other - res1 * self return res1, res2 - # Note: TimedeltaIndex overrides this in call to cls._add_numeric_methods def __neg__(self): if self.freq is not None: return type(self)(-self._data, freq=-self.freq) return type(self)(-self._data) + def __pos__(self): + return type(self)(self._data, freq=self.freq) + def __abs__(self): # Note: freq is not preserved return type(self)(np.abs(self._data)) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 4e098b2f8be9b..5f17dde01d2c4 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -695,7 +695,6 @@ def __array_wrap__(self, result, context=None): return result attrs = self._get_attributes_dict() - attrs = self._maybe_update_attributes(attrs) return Index(result, **attrs) @cache_readonly @@ -5335,12 +5334,6 @@ def _add_numeric_methods_disabled(cls): cls.__abs__ = make_invalid_op("__abs__") cls.__inv__ = make_invalid_op("__inv__") - def _maybe_update_attributes(self, attrs): - """ - Update Index attributes (e.g. freq) depending on op. - """ - return attrs - @classmethod def _add_numeric_methods_binary(cls): """ @@ -5374,7 +5367,6 @@ def _make_evaluate_unary(op, opstr): def _evaluate_numeric_unary(self): attrs = self._get_attributes_dict() - attrs = self._maybe_update_attributes(attrs) return Index(op(self.values), **attrs) _evaluate_numeric_unary.__name__ = opstr diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index af99c7a2754e5..c7664d9777c71 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -15,6 +15,7 @@ from pandas.core.dtypes.common import ( ensure_int64, + is_bool_dtype, is_dtype_equal, is_float, is_integer, @@ -163,6 +164,20 @@ def values(self): def asi8(self): return self._data.asi8 + def __array_wrap__(self, result, context=None): + """ + Gets called after a ufunc. + """ + 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) and attrs["freq"]: + # no need to infer if freq is None + attrs["freq"] = "infer" + return Index(result, **attrs) + # ------------------------------------------------------------------------ def equals(self, other): diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 9f2b31f23d2fa..caae9a0b5f751 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -465,14 +465,6 @@ def _convert_for_op(self, value): return _to_M8(value) raise ValueError("Passed item and index have different timezone") - def _maybe_update_attributes(self, attrs): - """ Update Index attributes (e.g. freq) depending on op """ - freq = attrs.get("freq", None) - if freq is not None: - # no need to infer if freq is None - attrs["freq"] = "infer" - return attrs - # -------------------------------------------------------------------- # Rendering Methods diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index cfdaf65955dab..43ed6e7b122ea 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -75,7 +75,7 @@ class RangeIndex(Int64Index): _engine_type = libindex.Int64Engine _range = None # type: range - # check whether self._data has benn called + # check whether self._data has been called _cached_data = None # type: np.ndarray # -------------------------------------------------------------------- # Constructors @@ -785,7 +785,6 @@ def _evaluate_numeric_binop(self, other): other = extract_array(other, extract_numpy=True) attrs = self._get_attributes_dict() - attrs = self._maybe_update_attributes(attrs) left, right = self, other diff --git a/pandas/core/indexes/timedeltas.py b/pandas/core/indexes/timedeltas.py index f2ce562536b95..d06afa3daa792 100644 --- a/pandas/core/indexes/timedeltas.py +++ b/pandas/core/indexes/timedeltas.py @@ -44,7 +44,12 @@ class TimedeltaDelegateMixin(DatetimelikeDelegateMixin): # which we we dont' want to expose in the .dt accessor. _delegate_class = TimedeltaArray _delegated_properties = TimedeltaArray._datetimelike_ops + ["components"] - _delegated_methods = TimedeltaArray._datetimelike_methods + ["_box_values"] + _delegated_methods = TimedeltaArray._datetimelike_methods + [ + "_box_values", + "__neg__", + "__pos__", + "__abs__", + ] _raw_properties = {"components"} _raw_methods = {"to_pytimedelta"} @@ -56,7 +61,7 @@ class TimedeltaDelegateMixin(DatetimelikeDelegateMixin): TimedeltaArray, TimedeltaDelegateMixin._delegated_methods, typ="method", - overwrite=False, + overwrite=True, ) class TimedeltaIndex( DatetimeIndexOpsMixin, dtl.TimelikeOps, Int64Index, TimedeltaDelegateMixin @@ -279,14 +284,6 @@ def __setstate__(self, state): _unpickle_compat = __setstate__ - def _maybe_update_attributes(self, attrs): - """ Update Index attributes (e.g. freq) depending on op """ - freq = attrs.get("freq", None) - if freq is not None: - # no need to infer if freq is None - attrs["freq"] = "infer" - return attrs - # ------------------------------------------------------------------- # Rendering Methods @@ -689,7 +686,6 @@ def delete(self, loc): TimedeltaIndex._add_comparison_ops() -TimedeltaIndex._add_numeric_methods_unary() TimedeltaIndex._add_logical_methods_disabled() TimedeltaIndex._add_datetimelike_methods()