Skip to content

Commit 3dbcda5

Browse files
authored
API: dont infer freq in DTA/TDA arithmetic ops (#33487)
1 parent 778dc60 commit 3dbcda5

File tree

8 files changed

+30
-24
lines changed

8 files changed

+30
-24
lines changed

pandas/core/arrays/datetimelike.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -1176,10 +1176,7 @@ def _add_timedeltalike_scalar(self, other):
11761176
# adding a scalar preserves freq
11771177
new_freq = self.freq
11781178

1179-
if new_freq is not None:
1180-
# fastpath that doesnt require inference
1181-
return type(self)(new_values, dtype=self.dtype, freq=new_freq)
1182-
return type(self)(new_values, dtype=self.dtype)._with_freq("infer")
1179+
return type(self)(new_values, dtype=self.dtype, freq=new_freq)
11831180

11841181
def _add_timedelta_arraylike(self, other):
11851182
"""
@@ -1209,7 +1206,7 @@ def _add_timedelta_arraylike(self, other):
12091206
mask = (self._isnan) | (other._isnan)
12101207
new_values[mask] = iNaT
12111208

1212-
return type(self)(new_values, dtype=self.dtype)._with_freq("infer")
1209+
return type(self)(new_values, dtype=self.dtype)
12131210

12141211
def _add_nat(self):
12151212
"""

pandas/core/arrays/datetimes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ def _add_offset(self, offset):
698698
# GH#30336 _from_sequence won't be able to infer self.tz
699699
return type(self)._from_sequence(result).tz_localize(self.tz)
700700

701-
return type(self)._from_sequence(result)._with_freq("infer")
701+
return type(self)._from_sequence(result)
702702

703703
def _sub_datetimelike_scalar(self, other):
704704
# subtract a datetime from myself, yielding a ndarray[timedelta64[ns]]

pandas/core/indexes/datetimelike.py

+5
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,11 @@ def _set_freq(self, freq):
625625
# GH#29843
626626
self._data._with_freq(freq)
627627

628+
def _with_freq(self, freq):
629+
index = self.copy(deep=False)
630+
index._set_freq(freq)
631+
return index
632+
628633
def _shallow_copy(self, values=None, name: Label = lib.no_default):
629634
name = self.name if name is lib.no_default else name
630635
cache = self._cache.copy() if values is None else {}

pandas/core/indexes/timedeltas.py

-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
"std",
4949
"median",
5050
"_format_native_types",
51-
"freq",
5251
],
5352
TimedeltaArray,
5453
)

pandas/tests/arithmetic/test_datetime64.py

+14-14
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ def test_dt64arr_add_sub_td64ndarray(self, tz_naive_fixture, box_with_array):
865865
tdi = pd.TimedeltaIndex(["-1 Day", "-1 Day", "-1 Day"])
866866
tdarr = tdi.values
867867

868-
expected = pd.date_range("2015-12-31", periods=3, tz=tz)
868+
expected = pd.date_range("2015-12-31", "2016-01-02", periods=3, tz=tz)
869869

870870
dtarr = tm.box_expected(dti, box_with_array)
871871
expected = tm.box_expected(expected, box_with_array)
@@ -875,7 +875,7 @@ def test_dt64arr_add_sub_td64ndarray(self, tz_naive_fixture, box_with_array):
875875
result = tdarr + dtarr
876876
tm.assert_equal(result, expected)
877877

878-
expected = pd.date_range("2016-01-02", periods=3, tz=tz)
878+
expected = pd.date_range("2016-01-02", "2016-01-04", periods=3, tz=tz)
879879
expected = tm.box_expected(expected, box_with_array)
880880

881881
result = dtarr - tdarr
@@ -1385,13 +1385,13 @@ def test_dt64arr_add_sub_DateOffset(self, box_with_array):
13851385
s = tm.box_expected(s, box_with_array)
13861386
result = s + pd.DateOffset(years=1)
13871387
result2 = pd.DateOffset(years=1) + s
1388-
exp = date_range("2001-01-01", "2001-01-31", name="a")
1388+
exp = date_range("2001-01-01", "2001-01-31", name="a")._with_freq(None)
13891389
exp = tm.box_expected(exp, box_with_array)
13901390
tm.assert_equal(result, exp)
13911391
tm.assert_equal(result2, exp)
13921392

13931393
result = s - pd.DateOffset(years=1)
1394-
exp = date_range("1999-01-01", "1999-01-31", name="a")
1394+
exp = date_range("1999-01-01", "1999-01-31", name="a")._with_freq(None)
13951395
exp = tm.box_expected(exp, box_with_array)
13961396
tm.assert_equal(result, exp)
13971397

@@ -1553,7 +1553,7 @@ def test_dti_add_sub_nonzero_mth_offset(
15531553
mth = getattr(date, op)
15541554
result = mth(offset)
15551555

1556-
expected = pd.DatetimeIndex(exp, tz=tz, freq=exp_freq)
1556+
expected = pd.DatetimeIndex(exp, tz=tz)
15571557
expected = tm.box_expected(expected, box_with_array, False)
15581558
tm.assert_equal(result, expected)
15591559

@@ -2344,29 +2344,29 @@ def test_ufunc_coercions(self):
23442344
assert result.freq == "2D"
23452345

23462346
exp = date_range("2010-12-31", periods=3, freq="2D", name="x")
2347+
23472348
for result in [idx - delta, np.subtract(idx, delta)]:
23482349
assert isinstance(result, DatetimeIndex)
23492350
tm.assert_index_equal(result, exp)
23502351
assert result.freq == "2D"
23512352

2353+
# When adding/subtracting an ndarray (which has no .freq), the result
2354+
# does not infer freq
2355+
idx = idx._with_freq(None)
23522356
delta = np.array(
23532357
[np.timedelta64(1, "D"), np.timedelta64(2, "D"), np.timedelta64(3, "D")]
23542358
)
2355-
exp = DatetimeIndex(
2356-
["2011-01-02", "2011-01-05", "2011-01-08"], freq="3D", name="x"
2357-
)
2359+
exp = DatetimeIndex(["2011-01-02", "2011-01-05", "2011-01-08"], name="x")
2360+
23582361
for result in [idx + delta, np.add(idx, delta)]:
2359-
assert isinstance(result, DatetimeIndex)
23602362
tm.assert_index_equal(result, exp)
2361-
assert result.freq == "3D"
2363+
assert result.freq == exp.freq
23622364

2363-
exp = DatetimeIndex(
2364-
["2010-12-31", "2011-01-01", "2011-01-02"], freq="D", name="x"
2365-
)
2365+
exp = DatetimeIndex(["2010-12-31", "2011-01-01", "2011-01-02"], name="x")
23662366
for result in [idx - delta, np.subtract(idx, delta)]:
23672367
assert isinstance(result, DatetimeIndex)
23682368
tm.assert_index_equal(result, exp)
2369-
assert result.freq == "D"
2369+
assert result.freq == exp.freq
23702370

23712371
@pytest.mark.parametrize(
23722372
"names", [("foo", None, None), ("baz", "bar", None), ("bar", "bar", "bar")]

pandas/tests/arithmetic/test_timedelta64.py

+1
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ def test_timedelta(self, freq):
491491

492492
shifted = index + timedelta(1)
493493
back = shifted + timedelta(-1)
494+
back = back._with_freq("infer")
494495
tm.assert_index_equal(index, back)
495496

496497
if freq == "D":

pandas/tests/indexes/timedeltas/test_shift.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ def test_tdi_shift_minutes(self):
3838

3939
def test_tdi_shift_int(self):
4040
# GH#8083
41-
trange = pd.to_timedelta(range(5), unit="d") + pd.offsets.Hour(1)
41+
tdi = pd.to_timedelta(range(5), unit="d")
42+
trange = tdi._with_freq("infer") + pd.offsets.Hour(1)
4243
result = trange.shift(1)
4344
expected = TimedeltaIndex(
4445
[
@@ -54,7 +55,8 @@ def test_tdi_shift_int(self):
5455

5556
def test_tdi_shift_nonstandard_freq(self):
5657
# GH#8083
57-
trange = pd.to_timedelta(range(5), unit="d") + pd.offsets.Hour(1)
58+
tdi = pd.to_timedelta(range(5), unit="d")
59+
trange = tdi._with_freq("infer") + pd.offsets.Hour(1)
5860
result = trange.shift(3, freq="2D 1s")
5961
expected = TimedeltaIndex(
6062
[

pandas/tests/indexes/timedeltas/test_timedelta.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ def indices(self):
3030
return tm.makeTimedeltaIndex(10)
3131

3232
def create_index(self) -> TimedeltaIndex:
33-
return pd.to_timedelta(range(5), unit="d") + pd.offsets.Hour(1)
33+
index = pd.to_timedelta(range(5), unit="d")._with_freq("infer")
34+
assert index.freq == "D"
35+
return index + pd.offsets.Hour(1)
3436

3537
def test_numeric_compat(self):
3638
# Dummy method to override super's version; this test is now done

0 commit comments

Comments
 (0)