Skip to content

Commit 3e1f13c

Browse files
committed
TST: addtl tests for TimedeltaIndex/DatetimeIndex sub ops
DOC: revised timedeltas.rst a bit
1 parent fefc613 commit 3e1f13c

File tree

6 files changed

+50
-12
lines changed

6 files changed

+50
-12
lines changed

doc/source/timedeltas.rst

+30-5
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ You can construct a ``Timedelta`` scalar thru various arguments:
5656
Timedelta(timedelta(days=1,seconds=1))
5757
Timedelta(np.timedelta64(1,'ms'))
5858
59+
# negative Timedeltas have this string repr
60+
# to be more consistent with datetime.timedelta conventions
61+
Timedelta('-1us')
62+
5963
# a NaT
6064
Timedelta('nan')
6165
Timedelta('nat')
@@ -160,7 +164,7 @@ Operands can also appear in a reversed order (a singular object operated with a
160164
df.idxmin()
161165
df.idxmax()
162166
163-
``min, max, idxmin, idxmax`` operations are supported on Series / DataFrames. A single result will be a ``Timedelta``.
167+
``min, max, idxmin, idxmax`` operations are supported on Series as well. A scalar result will be a ``Timedelta``.
164168

165169
.. ipython:: python
166170
@@ -184,6 +188,7 @@ You can also negate, multiply and use ``abs`` on ``Timedeltas``
184188
.. ipython:: python
185189
186190
td1 = Timedelta('-1 days 2 hours 3 seconds')
191+
tdi
187192
-1 * td1
188193
- td1
189194
abs(td1)
@@ -193,14 +198,17 @@ You can also negate, multiply and use ``abs`` on ``Timedeltas``
193198
Reductions
194199
----------
195200

196-
Numeric reduction operation for ``timedelta64[ns]`` will return ``Timedelta`` objects.
201+
Numeric reduction operation for ``timedelta64[ns]`` will return ``Timedelta`` objects. As usual
202+
``NaT`` are skipped during evaluation.
197203

198204
.. ipython:: python
199205
200-
y2 = y.fillna(timedelta(days=-1,seconds=5))
206+
y2 = Series(to_timedelta(['-1 days +00:00:05','nat','-1 days +00:00:05','1 days']))
201207
y2
202208
y2.mean()
209+
y2.median()
203210
y2.quantile(.1)
211+
y2.sum()
204212
205213
.. _timedeltas.timedeltas_convert:
206214

@@ -336,6 +344,9 @@ Furthermore you can use partial string selection and the range will be inferred:
336344
337345
s['1 day':'1 day 5 hours']
338346
347+
Operations
348+
~~~~~~~~~~
349+
339350
Finally, the combination of ``TimedeltaIndex`` with ``DatetimeIndex`` allow certain combination operations that are NaT preserving:
340351

341352
.. ipython:: python
@@ -347,18 +358,32 @@ Finally, the combination of ``TimedeltaIndex`` with ``DatetimeIndex`` allow cert
347358
(dti + tdi).tolist()
348359
(dti - tdi).tolist()
349360
361+
Conversions
362+
~~~~~~~~~~~
363+
350364
Similarly to frequency conversion on a ``Series`` above, you can convert these indices to yield another Index.
351365

352366
.. ipython:: python
353367
354368
tdi / np.timedelta64(1,'s')
355369
tdi.astype('timedelta64[s]')
356370
357-
Scalars type ops work as well
371+
Scalars type ops work as well. These can potentially return a *different* type of index.
358372

359373
.. ipython:: python
360374
375+
# adding or timedelta and date -> datelike
361376
tdi + Timestamp('20130101')
362-
tdi + Timedelta('10 days')
377+
378+
# subtraction of a date and a timedelta -> datelike
379+
# note that trying to subtract a date from a Timedelta will raise an exception
363380
(Timestamp('20130101') - tdi).tolist()
381+
382+
# timedelta + timedelta -> timedelta
383+
tdi + Timedelta('10 days')
384+
385+
# division can result in a Timedelta if the divisor is an integer
386+
tdi / 2
387+
388+
# or a Float64Index if the divisor is a Timedelta
364389
tdi / tdi[0]

doc/source/v0.15.0.txt

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ users upgrade to this version.
1818
- The ``Categorical`` type was integrated as a first-class pandas type, see :ref:`here <whatsnew_0150.cat>`
1919
- New scalar type ``Timedelta``, and a new index type ``TimedeltaIndex``, see :ref:`here <whatsnew_0150.timedeltaindex>`
2020
- New datetimelike properties accessor ``.dt`` for Series, see :ref:`Datetimelike Properties <whatsnew_0150.dt>`
21-
- Split indexing documentation into :ref:`Indexing and Selecing Data <indexing>` and :ref:`MultiIndex / Advanced Indexing <advanced>`
21+
- Split indexing documentation into :ref:`Indexing and Selecting Data <indexing>` and :ref:`MultiIndex / Advanced Indexing <advanced>`
2222
- API change in using Indexes in set operations, see :ref:`here <whatsnew_0150.index_set_ops>`
2323
- Internal refactoring of the ``Index`` class to no longer sub-class ``ndarray``, see :ref:`Internal Refactoring <whatsnew_0150.refactoring>`
2424
- dropping support for ``PyTables`` less than version 3.0.0, and ``numexpr`` less than version 2.1 (:issue:`7990`)
@@ -511,6 +511,10 @@ Consruct a scalar
511511
Timedelta('15.5us')
512512
Timedelta('1 hour 15.5us')
513513

514+
# negative Timedeltas have this string repr
515+
# to be more consistent with datetime.timedelta conventions
516+
Timedelta('-1us')
517+
514518
# a NaT
515519
Timedelta('nan')
516520

pandas/core/index.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2063,9 +2063,9 @@ def _add_numeric_methods_disabled(cls):
20632063

20642064
def _make_invalid_op(opstr):
20652065

2066-
def _invalid_op(self, other):
2066+
def _invalid_op(self, other=None):
20672067
raise TypeError("cannot perform {opstr} with this index type: {typ}".format(opstr=opstr,
2068-
typ=type(self)))
2068+
typ=type(self)))
20692069
return _invalid_op
20702070

20712071
cls.__mul__ = cls.__rmul__ = _make_invalid_op('__mul__')

pandas/tseries/base.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,10 @@ def resolution(self):
312312
return get_reso_string(self._resolution)
313313

314314
def _add_datelike(self, other):
315-
return NotImplemented
315+
raise NotImplementedError
316316

317317
def _sub_datelike(self, other):
318-
return NotImplemented
318+
raise NotImplementedError
319319

320320
def __add__(self, other):
321321
from pandas.core.index import Index
@@ -326,7 +326,7 @@ def __add__(self, other):
326326
elif isinstance(self, TimedeltaIndex) and isinstance(other, Index):
327327
if hasattr(other,'_add_delta'):
328328
return other._add_delta(self)
329-
raise TypeError("cannot perform a numeric operation with a TimedeltaIndex and {typ}".format(typ=type(other)))
329+
raise TypeError("cannot add TimedeltaIndex and {typ}".format(typ=type(other)))
330330
elif isinstance(other, Index):
331331
return self.union(other)
332332
elif isinstance(other, (DateOffset, timedelta, np.timedelta64, tslib.Timedelta)):
@@ -344,8 +344,12 @@ def __sub__(self, other):
344344
from pandas.tseries.offsets import DateOffset
345345
if isinstance(other, TimedeltaIndex):
346346
return self._add_delta(-other)
347+
elif isinstance(self, TimedeltaIndex) and isinstance(other, Index):
348+
if not isinstance(other, TimedeltaIndex):
349+
raise TypeError("cannot subtract TimedeltaIndex and {typ}".format(typ=type(other)))
350+
return self._add_delta(-other)
347351
elif isinstance(other, Index):
348-
return self.diff(other)
352+
return self.difference(other)
349353
elif isinstance(other, (DateOffset, timedelta, np.timedelta64, tslib.Timedelta)):
350354
return self._add_delta(-other)
351355
elif com.is_integer(other):

pandas/tseries/tdi.py

+3
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,9 @@ def _add_datelike(self, other):
327327
result[mask] = tslib.iNaT
328328
return DatetimeIndex(result,name=self.name,copy=False)
329329

330+
def _sub_datelike(self, other):
331+
raise TypeError("cannot subtract a datelike from a TimedeltaIndex")
332+
330333
def _format_native_types(self, na_rep=u('NaT'),
331334
date_format=None, **kwargs):
332335
from pandas.core.format import Timedelta64Formatter

pandas/tseries/tests/test_base.py

+2
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,8 @@ def test_subtraction_ops(self):
445445

446446
self.assertRaises(TypeError, lambda : tdi - dt)
447447
self.assertRaises(TypeError, lambda : tdi - dti)
448+
self.assertRaises(TypeError, lambda : td - dt)
449+
self.assertRaises(TypeError, lambda : td - dti)
448450

449451
result = dt-dti
450452
expected = TimedeltaIndex(['0 days','-1 days','-2 days'])

0 commit comments

Comments
 (0)