Skip to content

Commit 5e3cd25

Browse files
jbrockmendeljreback
authored andcommitted
Make TimedeltaIndex +/- pd.NaT return TimedeltaIndex (#19139)
1 parent aa9e002 commit 5e3cd25

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

doc/source/whatsnew/v0.23.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ Other API Changes
273273
- The default ``Timedelta`` constructor now accepts an ``ISO 8601 Duration`` string as an argument (:issue:`19040`)
274274
- ``IntervalDtype`` now returns ``True`` when compared against ``'interval'`` regardless of subtype, and ``IntervalDtype.name`` now returns ``'interval'`` regardless of subtype (:issue:`18980`)
275275
- :func:`Series.to_csv` now accepts a ``compression`` argument that works in the same way as the ``compression`` argument in :func:`DataFrame.to_csv` (:issue:`18958`)
276+
- Addition or subtraction of ``NaT`` from :class:`TimedeltaIndex` will return ``TimedeltaIndex`` instead of ``DatetimeIndex`` (:issue:`19124`)
276277

277278
.. _whatsnew_0230.deprecations:
278279

pandas/core/indexes/timedeltas.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,8 @@ def _add_datelike(self, other):
403403
# adding a timedeltaindex to a datetimelike
404404
from pandas import Timestamp, DatetimeIndex
405405
if other is NaT:
406-
result = self._nat_new(box=False)
406+
# GH#19124 pd.NaT is treated like a timedelta
407+
return self._nat_new()
407408
else:
408409
other = Timestamp(other)
409410
i8 = self.asi8
@@ -413,12 +414,13 @@ def _add_datelike(self, other):
413414
return DatetimeIndex(result, name=self.name, copy=False)
414415

415416
def _sub_datelike(self, other):
416-
from pandas import DatetimeIndex
417+
# GH#19124 Timedelta - datetime is not in general well-defined.
418+
# We make an exception for pd.NaT, which in this case quacks
419+
# like a timedelta.
417420
if other is NaT:
418-
result = self._nat_new(box=False)
421+
return self._nat_new()
419422
else:
420423
raise TypeError("cannot subtract a datelike from a TimedeltaIndex")
421-
return DatetimeIndex(result, name=self.name, copy=False)
422424

423425
def _add_offset_array(self, other):
424426
# Array/Index of DateOffset objects

pandas/tests/scalar/test_nat.py

+23-7
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,30 @@ def test_nat_arithmetic_index():
302302
tm.assert_index_equal(left - right, exp)
303303
tm.assert_index_equal(right - left, exp)
304304

305-
# timedelta
305+
# timedelta # GH#19124
306306
tdi = TimedeltaIndex(['1 day', '2 day'], name='x')
307-
exp = DatetimeIndex([NaT, NaT], name='x')
308-
for (left, right) in [(NaT, tdi)]:
309-
tm.assert_index_equal(left + right, exp)
310-
tm.assert_index_equal(right + left, exp)
311-
tm.assert_index_equal(left - right, exp)
312-
tm.assert_index_equal(right - left, exp)
307+
tdi_nat = TimedeltaIndex([NaT, NaT], name='x')
308+
309+
tm.assert_index_equal(tdi + NaT, tdi_nat)
310+
tm.assert_index_equal(NaT + tdi, tdi_nat)
311+
tm.assert_index_equal(tdi - NaT, tdi_nat)
312+
tm.assert_index_equal(NaT - tdi, tdi_nat)
313+
314+
315+
@pytest.mark.parametrize('box, assert_func', [
316+
(TimedeltaIndex, tm.assert_index_equal),
317+
pytest.param(Series, tm.assert_series_equal,
318+
marks=pytest.mark.xfail(reason='NaT - Series returns NaT'))
319+
])
320+
def test_nat_arithmetic_td64_vector(box, assert_func):
321+
# GH#19124
322+
vec = box(['1 day', '2 day'], dtype='timedelta64[ns]')
323+
box_nat = box([NaT, NaT], dtype='timedelta64[ns]')
324+
325+
assert_func(vec + NaT, box_nat)
326+
assert_func(NaT + vec, box_nat)
327+
assert_func(vec - NaT, box_nat)
328+
assert_func(NaT - vec, box_nat)
313329

314330

315331
def test_nat_pinned_docstrings():

0 commit comments

Comments
 (0)