Skip to content

Commit 1879678

Browse files
jbrockmendelyehoshuadimarsky
authored andcommitted
ENH: TDA.__mul__ support non-nano (pandas-dev#47668)
* ENH: TDA.__mul__ support non-nano * fix freq
1 parent aa309a7 commit 1879678

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

pandas/core/arrays/timedeltas.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ def __mul__(self, other) -> TimedeltaArray:
398398
freq = None
399399
if self.freq is not None and not isna(other):
400400
freq = self.freq * other
401-
return type(self)(result, freq=freq)
401+
return type(self)._simple_new(result, dtype=result.dtype, freq=freq)
402402

403403
if not hasattr(other, "dtype"):
404404
# list, tuple
@@ -412,13 +412,14 @@ def __mul__(self, other) -> TimedeltaArray:
412412
# this multiplication will succeed only if all elements of other
413413
# are int or float scalars, so we will end up with
414414
# timedelta64[ns]-dtyped result
415-
result = [self[n] * other[n] for n in range(len(self))]
415+
arr = self._ndarray
416+
result = [arr[n] * other[n] for n in range(len(self))]
416417
result = np.array(result)
417-
return type(self)(result)
418+
return type(self)._simple_new(result, dtype=result.dtype)
418419

419420
# numpy will accept float or int dtype, raise TypeError for others
420421
result = self._ndarray * other
421-
return type(self)(result)
422+
return type(self)._simple_new(result, dtype=result.dtype)
422423

423424
__rmul__ = __mul__
424425

@@ -446,7 +447,8 @@ def __truediv__(self, other):
446447
if self.freq is not None:
447448
# Tick division is not implemented, so operate on Timedelta
448449
freq = self.freq.delta / other
449-
return type(self)(result, freq=freq)
450+
freq = to_offset(freq)
451+
return type(self)._simple_new(result, dtype=result.dtype, freq=freq)
450452

451453
if not hasattr(other, "dtype"):
452454
# e.g. list, tuple
@@ -462,6 +464,7 @@ def __truediv__(self, other):
462464
elif is_object_dtype(other.dtype):
463465
# We operate on raveled arrays to avoid problems in inference
464466
# on NaT
467+
# TODO: tests with non-nano
465468
srav = self.ravel()
466469
orav = other.ravel()
467470
result_list = [srav[n] / orav[n] for n in range(len(srav))]
@@ -488,7 +491,7 @@ def __truediv__(self, other):
488491

489492
else:
490493
result = self._ndarray / other
491-
return type(self)(result)
494+
return type(self)._simple_new(result, dtype=result.dtype)
492495

493496
@unpack_zerodim_and_defer("__rtruediv__")
494497
def __rtruediv__(self, other):

pandas/tests/arrays/test_timedeltas.py

+49
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from datetime import timedelta
2+
13
import numpy as np
24
import pytest
35

@@ -90,6 +92,53 @@ def test_add_pdnat(self, tda):
9092
assert result._reso == tda._reso
9193
assert result.isna().all()
9294

95+
def test_mul_scalar(self, tda):
96+
other = 2
97+
result = tda * other
98+
expected = TimedeltaArray._simple_new(tda._ndarray * other, dtype=tda.dtype)
99+
tm.assert_extension_array_equal(result, expected)
100+
assert result._reso == tda._reso
101+
102+
def test_mul_listlike(self, tda):
103+
other = np.arange(len(tda))
104+
result = tda * other
105+
expected = TimedeltaArray._simple_new(tda._ndarray * other, dtype=tda.dtype)
106+
tm.assert_extension_array_equal(result, expected)
107+
assert result._reso == tda._reso
108+
109+
def test_mul_listlike_object(self, tda):
110+
other = np.arange(len(tda))
111+
result = tda * other.astype(object)
112+
expected = TimedeltaArray._simple_new(tda._ndarray * other, dtype=tda.dtype)
113+
tm.assert_extension_array_equal(result, expected)
114+
assert result._reso == tda._reso
115+
116+
def test_div_numeric_scalar(self, tda):
117+
other = 2
118+
result = tda / other
119+
expected = TimedeltaArray._simple_new(tda._ndarray / other, dtype=tda.dtype)
120+
tm.assert_extension_array_equal(result, expected)
121+
assert result._reso == tda._reso
122+
123+
def test_div_td_scalar(self, tda):
124+
other = timedelta(seconds=1)
125+
result = tda / other
126+
expected = tda._ndarray / np.timedelta64(1, "s")
127+
tm.assert_numpy_array_equal(result, expected)
128+
129+
def test_div_numeric_array(self, tda):
130+
other = np.arange(len(tda))
131+
result = tda / other
132+
expected = TimedeltaArray._simple_new(tda._ndarray / other, dtype=tda.dtype)
133+
tm.assert_extension_array_equal(result, expected)
134+
assert result._reso == tda._reso
135+
136+
def test_div_td_array(self, tda):
137+
other = tda._ndarray + tda._ndarray[-1]
138+
result = tda / other
139+
expected = tda._ndarray / other
140+
tm.assert_numpy_array_equal(result, expected)
141+
93142

94143
class TestTimedeltaArray:
95144
@pytest.mark.parametrize("dtype", [int, np.int32, np.int64, "uint32", "uint64"])

0 commit comments

Comments
 (0)