Skip to content

Commit

Permalink
Enable subtracting a scalar cftime.datetime object from a CFTimeIndex (
Browse files Browse the repository at this point in the history
…#2672)

* Enable subtracting a scalar cftime.datetime object from a CFTimeIndex

* lint

* Test cftime.datetime minus CFTimeIndex as well

* Fix cftime minus CFTimeIndex
  • Loading branch information
spencerkclark authored and dcherian committed Jan 30, 2019
1 parent e8bf4bf commit fd2552a
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
4 changes: 4 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ Bug fixes
`Spencer Clark <https://github.com/spencerkclark>`_.
- Line plots with the `x` argument set to a non-dimensional coord now plot the correct data for 1D DataArrays.
(:issue:`27251). By `Tom Nicholas <http://github.com/TomNicholas>`_.
- Subtracting a scalar ``cftime.datetime`` object from a
:py:class:`CFTimeIndex` now results in a :py:class:`pandas.TimedeltaIndex`
instead of raising a ``TypeError`` (:issue:`2671`). By `Spencer Clark
<https://github.com/spencerkclark>`_.

.. _whats-new.0.11.3:

Expand Down
6 changes: 5 additions & 1 deletion xarray/coding/cftimeindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,13 +408,17 @@ def __radd__(self, other):
return CFTimeIndex(other + np.array(self))

def __sub__(self, other):
if isinstance(other, CFTimeIndex):
import cftime
if isinstance(other, (CFTimeIndex, cftime.datetime)):
return pd.TimedeltaIndex(np.array(self) - np.array(other))
elif isinstance(other, pd.TimedeltaIndex):
return CFTimeIndex(np.array(self) - other.to_pytimedelta())
else:
return CFTimeIndex(np.array(self) - other)

def __rsub__(self, other):
return pd.TimedeltaIndex(other - np.array(self))

def _add_delta(self, deltas):
# To support TimedeltaIndex + CFTimeIndex with older versions of
# pandas. No longer used as of pandas 0.23.
Expand Down
20 changes: 20 additions & 0 deletions xarray/tests/test_cftimeindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,26 @@ def test_cftimeindex_sub_cftimeindex(calendar):
assert isinstance(result, pd.TimedeltaIndex)


@pytest.mark.skipif(not has_cftime, reason='cftime not installed')
@pytest.mark.parametrize('calendar', _CFTIME_CALENDARS)
def test_cftimeindex_sub_cftime_datetime(calendar):
a = xr.cftime_range('2000', periods=5, calendar=calendar)
result = a - a[0]
expected = pd.TimedeltaIndex([timedelta(days=i) for i in range(5)])
assert result.equals(expected)
assert isinstance(result, pd.TimedeltaIndex)


@pytest.mark.skipif(not has_cftime, reason='cftime not installed')
@pytest.mark.parametrize('calendar', _CFTIME_CALENDARS)
def test_cftime_datetime_sub_cftimeindex(calendar):
a = xr.cftime_range('2000', periods=5, calendar=calendar)
result = a[0] - a
expected = pd.TimedeltaIndex([timedelta(days=-i) for i in range(5)])
assert result.equals(expected)
assert isinstance(result, pd.TimedeltaIndex)


@pytest.mark.skipif(not has_cftime, reason='cftime not installed')
@pytest.mark.parametrize('calendar', _CFTIME_CALENDARS)
def test_cftimeindex_sub_timedeltaindex(calendar):
Expand Down

0 comments on commit fd2552a

Please sign in to comment.