diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 43e380abd8bb53..fc046e90e8503d 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -441,7 +441,7 @@ Datetimelike Timedelta ^^^^^^^^^ -- +- Fixed bug where array of timestamp and deltas raised a TypeError: unsupported operand type(s) for -: 'numpy.ndarray' and 'Timedelta' (:issue:`21980`) - - diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index f7a6cf0c6dafc2..509f8b71d92094 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -542,10 +542,14 @@ def _binary_op_method_timedeltalike(op, name): elif hasattr(other, 'dtype'): # nd-array like - if other.dtype.kind not in ['m', 'M']: + if other.dtype.kind not in ['m', 'M', 'O']: # raise rathering than letting numpy return wrong answer return NotImplemented - return op(self.to_timedelta64(), other) + try: + converted_other = other.astype('datetime64[ns]') + return op(self.to_timedelta64(), converted_other) + except: + return NotImplemented elif not _validate_ops_compat(other): return NotImplemented @@ -929,7 +933,7 @@ cdef class _Timedelta(timedelta): def nanoseconds(self): """ Return the number of nanoseconds (n), where 0 <= n < 1 microsecond. - + Returns ------- int diff --git a/pandas/tests/series/test_timeseries.py b/pandas/tests/series/test_timeseries.py index 376b4d71f81e8a..853ea70aecaeca 100644 --- a/pandas/tests/series/test_timeseries.py +++ b/pandas/tests/series/test_timeseries.py @@ -1012,3 +1012,22 @@ def test_get_level_values_box(self): index = MultiIndex(levels=levels, labels=labels) assert isinstance(index.get_level_values(0)[0], Timestamp) + + def test_diff_sub_timedelta(self): + # GH 21980 + arr = np.array([Timestamp('20130101 9:01'), + Timestamp('20121230 9:02')]) + exp = np.array([Timestamp('20121231 9:01'), + Timestamp('20121229 9:02')]).astype('datetime64[ns]') + res = arr - pd.Timedelta('1D') + tm.assert_numpy_array_equal(res, exp) + + def test_diff_sub_timedelta_mixed(self): + # GH 21980 + now = pd.Timestamp.now() + arr = np.array([now, + Timestamp('20121230 9:02')]) + exp = np.array([now - pd.Timedelta('1D'), + Timestamp('20121229 9:02')]).astype('datetime64[ns]') + res = arr - pd.Timedelta('1D') + tm.assert_numpy_array_equal(res, exp)