Skip to content

Commit 4e4f72e

Browse files
BUG: Fixed inconsistent multiplication behavior pandas-dev#47953
1 parent 96b036c commit 4e4f72e

File tree

3 files changed

+36
-6
lines changed

3 files changed

+36
-6
lines changed

doc/source/whatsnew/v1.5.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ Datetimelike
827827
- Bug in :meth:`DatetimeIndex.resolution` incorrectly returning "day" instead of "nanosecond" for nanosecond-resolution indexes (:issue:`46903`)
828828
- Bug in :class:`Timestamp` with an integer or float value and ``unit="Y"`` or ``unit="M"`` giving slightly-wrong results (:issue:`47266`)
829829
- Bug in :class:`.DatetimeArray` construction when passed another :class:`.DatetimeArray` and ``freq=None`` incorrectly inferring the freq from the given array (:issue:`47296`)
830+
- Bug in :meth:`RelativeDeltaOffset._apply` which caused inconsistent behavior upon multiplying a :class:`DateOffset` (:issue:`47953`)
830831
-
831832

832833
Timedelta

pandas/_libs/tslibs/offsets.pyx

+1-6
Original file line numberDiff line numberDiff line change
@@ -1109,12 +1109,7 @@ cdef class RelativeDeltaOffset(BaseOffset):
11091109
else:
11101110
td_nano = Timedelta(0)
11111111

1112-
if self.n > 0:
1113-
for i in range(self.n):
1114-
other = other + self._offset + td_nano
1115-
else:
1116-
for i in range(-self.n):
1117-
other = other - self._offset - td_nano
1112+
other = other + ((self._offset + td_nano) * self.n)
11181113

11191114
if tzinfo is not None and self._use_relativedelta:
11201115
# bring tz back from UTC calculation

pandas/tests/tseries/offsets/test_offsets.py

+34
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
from pandas.errors import PerformanceWarning
3333

3434
from pandas import (
35+
DataFrame,
3536
DatetimeIndex,
37+
Series,
3638
date_range,
3739
)
3840
import pandas._testing as tm
@@ -1032,3 +1034,35 @@ def test_construct_int_arg_no_kwargs_assumed_days(n):
10321034
result = Timestamp(2022, 1, 2) + offset
10331035
expected = Timestamp(2022, 1, 2 + n)
10341036
assert result == expected
1037+
1038+
1039+
def test_offset_multiplication():
1040+
# GH#47953
1041+
mo1 = DateOffset(months=1)
1042+
mo2 = DateOffset(months=2)
1043+
1044+
startscalar = Timestamp("2020-01-30")
1045+
startarray = Series([Timestamp("2020-01-30")])
1046+
1047+
resultscalar1 = startscalar + (mo1 * 2)
1048+
resultscalar2 = startscalar + mo2
1049+
resultarray1 = startarray + (mo1 * 2)
1050+
resultarray2 = startarray + mo2
1051+
1052+
expectedscalar = Timestamp("2020-03-30")
1053+
expectedarray = Series([Timestamp("2020-03-30")])
1054+
assert resultscalar1 == expectedscalar
1055+
assert resultscalar2 == expectedscalar
1056+
tm.assert_series_equal(resultarray1, expectedarray)
1057+
tm.assert_series_equal(resultarray2, expectedarray)
1058+
1059+
df = DataFrame({"T": [Timestamp("2019-04-30")], "D": [DateOffset(months=1)]})
1060+
frameresult1 = df["T"] + 26 * df["D"]
1061+
df2 = DataFrame(
1062+
{
1063+
"T": [Timestamp("2019-04-30"), Timestamp("2019-04-30")],
1064+
"D": [DateOffset(months=1), DateOffset(months=1)],
1065+
}
1066+
)
1067+
frameresult2 = df2["T"] + 26 * df2["D"]
1068+
assert frameresult1[0] == frameresult2[0]

0 commit comments

Comments
 (0)