Skip to content

Make TimedeltaIndex +/- pd.NaT return TimedeltaIndex #19139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 16, 2018
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.23.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ Other API Changes
- Subtraction of :class:`Series` with timezone-aware ``dtype='datetime64[ns]'`` with mis-matched timezones will raise ``TypeError`` instead of ``ValueError`` (issue:`18817`)
- :class:`IntervalIndex` and ``IntervalDtype`` no longer support categorical, object, and string subtypes (:issue:`19016`)
- The default ``Timedelta`` constructor now accepts an ``ISO 8601 Duration`` string as an argument (:issue:`19040`)
- Addition or subtraction of ``NaT`` from :class:`TimedeltaIndex` will return ``TimedeltaIndex`` instead of ``DatetimeIndex`` (:issue:`19124`)

.. _whatsnew_0230.deprecations:

Expand Down
10 changes: 6 additions & 4 deletions pandas/core/indexes/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,8 @@ def _add_datelike(self, other):
# adding a timedeltaindex to a datetimelike
from pandas import Timestamp, DatetimeIndex
if other is NaT:
result = self._nat_new(box=False)
# GH#19124 pd.NaT is treated like a timedelta
return self._nat_new()
else:
other = Timestamp(other)
i8 = self.asi8
Expand All @@ -413,12 +414,13 @@ def _add_datelike(self, other):
return DatetimeIndex(result, name=self.name, copy=False)

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

def _add_offset_array(self, other):
# Array/Index of DateOffset objects
Expand Down
30 changes: 23 additions & 7 deletions pandas/tests/scalar/test_nat.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,14 +302,30 @@ def test_nat_arithmetic_index():
tm.assert_index_equal(left - right, exp)
tm.assert_index_equal(right - left, exp)

# timedelta
# timedelta # GH#19124
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add similar testing for Series here as well

Copy link
Member Author

@jbrockmendel jbrockmendel Jan 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shoot this surfaces a new bug; I'll xfail for now.

tdi = TimedeltaIndex(['1 day', '2 day'], name='x')
exp = DatetimeIndex([NaT, NaT], name='x')
for (left, right) in [(NaT, tdi)]:
tm.assert_index_equal(left + right, exp)
tm.assert_index_equal(right + left, exp)
tm.assert_index_equal(left - right, exp)
tm.assert_index_equal(right - left, exp)
tdi_nat = TimedeltaIndex([NaT, NaT], name='x')

tm.assert_index_equal(tdi + NaT, tdi_nat)
tm.assert_index_equal(NaT + tdi, tdi_nat)
tm.assert_index_equal(tdi - NaT, tdi_nat)
tm.assert_index_equal(NaT - tdi, tdi_nat)


@pytest.mark.xfail(reason='NaT - Series returns NaT. This behavior was '
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you just parametrize around tdi and Series, too much repeated code (you can xfail that case using pytest.param)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls do this here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are pinging but not doing what I ask.

'introduced somewhere between 0.22.0 and '
'23fb3392adedd3a')
def test_nat_arithmetic_series():
# GH#19124
tdi = TimedeltaIndex(['1 day', '2 day'], name='x')
tdi_nat = TimedeltaIndex([NaT, NaT], name='x')
ser = Series(tdi)
ser_nat = Series(tdi_nat)

tm.assert_series_equal(ser + NaT, ser_nat)
tm.assert_series_equal(NaT + ser, ser_nat)
tm.assert_series_equal(ser - NaT, ser_nat)
tm.assert_series_equal(NaT - ser, ser_nat)


def test_nat_pinned_docstrings():
Expand Down