|
7 | 7 |
|
8 | 8 | import numpy as np
|
9 | 9 |
|
10 |
| -from pandas._libs import algos, tslibs |
| 10 | +from pandas._libs import algos, lib, tslibs |
11 | 11 | from pandas._libs.tslibs import NaT, Timedelta, Timestamp, iNaT
|
12 | 12 | from pandas._libs.tslibs.fields import get_timedelta_field
|
13 | 13 | from pandas._libs.tslibs.timedeltas import (
|
@@ -177,7 +177,7 @@ def __new__(cls, values, freq=None, dtype=_TD_DTYPE, copy=False):
|
177 | 177 | passed=freq.freqstr))
|
178 | 178 | elif freq is None:
|
179 | 179 | freq = inferred_freq
|
180 |
| - freq_infer = False |
| 180 | + freq_infer = False |
181 | 181 |
|
182 | 182 | result = cls._simple_new(values, freq=freq)
|
183 | 183 | # check that we are matching freqs
|
@@ -355,12 +355,108 @@ def _evaluate_with_timedelta_like(self, other, op):
|
355 | 355 |
|
356 | 356 | __mul__ = _wrap_tdi_op(operator.mul)
|
357 | 357 | __rmul__ = __mul__
|
358 |
| - __truediv__ = _wrap_tdi_op(operator.truediv) |
359 | 358 | __floordiv__ = _wrap_tdi_op(operator.floordiv)
|
360 | 359 | __rfloordiv__ = _wrap_tdi_op(ops.rfloordiv)
|
361 | 360 |
|
| 361 | + def __truediv__(self, other): |
| 362 | + # timedelta / X is well-defined for timedelta-like or numeric X |
| 363 | + other = lib.item_from_zerodim(other) |
| 364 | + |
| 365 | + if isinstance(other, (ABCSeries, ABCDataFrame, ABCIndexClass)): |
| 366 | + return NotImplemented |
| 367 | + |
| 368 | + if isinstance(other, (timedelta, np.timedelta64, Tick)): |
| 369 | + other = Timedelta(other) |
| 370 | + if other is NaT: |
| 371 | + # specifically timedelta64-NaT |
| 372 | + result = np.empty(self.shape, dtype=np.float64) |
| 373 | + result.fill(np.nan) |
| 374 | + return result |
| 375 | + |
| 376 | + # otherwise, dispatch to Timedelta implementation |
| 377 | + return self._data / other |
| 378 | + |
| 379 | + elif lib.is_scalar(other): |
| 380 | + # assume it is numeric |
| 381 | + result = self._data / other |
| 382 | + freq = None |
| 383 | + if self.freq is not None: |
| 384 | + # Tick division is not implemented, so operate on Timedelta |
| 385 | + freq = self.freq.delta / other |
| 386 | + return type(self)(result, freq=freq) |
| 387 | + |
| 388 | + if not hasattr(other, "dtype"): |
| 389 | + # e.g. list, tuple |
| 390 | + other = np.array(other) |
| 391 | + |
| 392 | + if len(other) != len(self): |
| 393 | + raise ValueError("Cannot divide vectors with unequal lengths") |
| 394 | + |
| 395 | + elif is_timedelta64_dtype(other): |
| 396 | + # let numpy handle it |
| 397 | + return self._data / other |
| 398 | + |
| 399 | + elif is_object_dtype(other): |
| 400 | + # Note: we do not do type inference on the result, so either |
| 401 | + # an object array or numeric-dtyped (if numpy does inference) |
| 402 | + # will be returned. GH#23829 |
| 403 | + result = [self[n] / other[n] for n in range(len(self))] |
| 404 | + result = np.array(result) |
| 405 | + return result |
| 406 | + |
| 407 | + else: |
| 408 | + result = self._data / other |
| 409 | + return type(self)(result) |
| 410 | + |
| 411 | + def __rtruediv__(self, other): |
| 412 | + # X / timedelta is defined only for timedelta-like X |
| 413 | + other = lib.item_from_zerodim(other) |
| 414 | + |
| 415 | + if isinstance(other, (ABCSeries, ABCDataFrame, ABCIndexClass)): |
| 416 | + return NotImplemented |
| 417 | + |
| 418 | + if isinstance(other, (timedelta, np.timedelta64, Tick)): |
| 419 | + other = Timedelta(other) |
| 420 | + if other is NaT: |
| 421 | + # specifically timedelta64-NaT |
| 422 | + result = np.empty(self.shape, dtype=np.float64) |
| 423 | + result.fill(np.nan) |
| 424 | + return result |
| 425 | + |
| 426 | + # otherwise, dispatch to Timedelta implementation |
| 427 | + return other / self._data |
| 428 | + |
| 429 | + elif lib.is_scalar(other): |
| 430 | + raise TypeError("Cannot divide {typ} by {cls}" |
| 431 | + .format(typ=type(other).__name__, |
| 432 | + cls=type(self).__name__)) |
| 433 | + |
| 434 | + if not hasattr(other, "dtype"): |
| 435 | + # e.g. list, tuple |
| 436 | + other = np.array(other) |
| 437 | + |
| 438 | + if len(other) != len(self): |
| 439 | + raise ValueError("Cannot divide vectors with unequal lengths") |
| 440 | + |
| 441 | + elif is_timedelta64_dtype(other): |
| 442 | + # let numpy handle it |
| 443 | + return other / self._data |
| 444 | + |
| 445 | + elif is_object_dtype(other): |
| 446 | + # Note: unlike in __truediv__, we do not _need_ to do type# |
| 447 | + # inference on the result. It does not raise, a numeric array |
| 448 | + # is returned. GH#23829 |
| 449 | + result = [other[n] / self[n] for n in range(len(self))] |
| 450 | + return np.array(result) |
| 451 | + |
| 452 | + else: |
| 453 | + raise TypeError("Cannot divide {dtype} data by {cls}" |
| 454 | + .format(dtype=other.dtype, |
| 455 | + cls=type(self).__name__)) |
| 456 | + |
362 | 457 | if compat.PY2:
|
363 | 458 | __div__ = __truediv__
|
| 459 | + __rdiv__ = __rtruediv__ |
364 | 460 |
|
365 | 461 | # Note: TimedeltaIndex overrides this in call to cls._add_numeric_methods
|
366 | 462 | def __neg__(self):
|
|
0 commit comments