Skip to content

Commit d40074f

Browse files
jbrockmendelmaxim veksler
authored and
maxim veksler
committed
simplify CBMonth.apply to remove roll_monthday (pandas-dev#19146)
1 parent bb431e1 commit d40074f

File tree

3 files changed

+35
-67
lines changed

3 files changed

+35
-67
lines changed

pandas/_libs/tslibs/offsets.pyx

-23
Original file line numberDiff line numberDiff line change
@@ -847,29 +847,6 @@ cpdef int roll_convention(int other, int n, int compare):
847847
return n
848848

849849

850-
cpdef int roll_monthday(datetime other, int n, datetime compare):
851-
"""
852-
Possibly increment or decrement the number of periods to shift
853-
based on rollforward/rollbackward conventions.
854-
855-
Parameters
856-
----------
857-
other : datetime
858-
n : number of periods to increment, before adjusting for rolling
859-
compare : datetime
860-
861-
Returns
862-
-------
863-
n : int number of periods to increment
864-
"""
865-
if n > 0 and other < compare:
866-
n -= 1
867-
elif n <= 0 and other > compare:
868-
# as if rolled forward already
869-
n += 1
870-
return n
871-
872-
873850
cpdef int roll_qtrday(datetime other, int n, int month, object day_opt,
874851
int modby=3) except? -1:
875852
"""

pandas/tests/tseries/offsets/test_liboffsets.py

-16
Original file line numberDiff line numberDiff line change
@@ -156,22 +156,6 @@ def test_roll_qtrday():
156156
assert roll_qtrday(other, n, month, 'business_end', modby=3) == n
157157

158158

159-
def test_roll_monthday():
160-
other = Timestamp('2017-12-29', tz='US/Pacific')
161-
before = Timestamp('2017-12-01', tz='US/Pacific')
162-
after = Timestamp('2017-12-31', tz='US/Pacific')
163-
164-
n = 42
165-
assert liboffsets.roll_monthday(other, n, other) == n
166-
assert liboffsets.roll_monthday(other, n, before) == n
167-
assert liboffsets.roll_monthday(other, n, after) == n - 1
168-
169-
n = -4
170-
assert liboffsets.roll_monthday(other, n, other) == n
171-
assert liboffsets.roll_monthday(other, n, before) == n + 1
172-
assert liboffsets.roll_monthday(other, n, after) == n
173-
174-
175159
def test_roll_convention():
176160
other = 29
177161
before = 1

pandas/tseries/offsets.py

+35-28
Original file line numberDiff line numberDiff line change
@@ -1039,55 +1039,62 @@ def __init__(self, n=1, normalize=False, weekmask='Mon Tue Wed Thu Fri',
10391039
_CustomMixin.__init__(self, weekmask, holidays, calendar)
10401040

10411041
@cache_readonly
1042-
def cbday(self):
1043-
kwds = self.kwds
1044-
return CustomBusinessDay(n=self.n, normalize=self.normalize, **kwds)
1042+
def cbday_roll(self):
1043+
"""Define default roll function to be called in apply method"""
1044+
cbday = CustomBusinessDay(n=self.n, normalize=False, **self.kwds)
1045+
1046+
if self._prefix.endswith('S'):
1047+
# MonthBegin
1048+
roll_func = cbday.rollforward
1049+
else:
1050+
# MonthEnd
1051+
roll_func = cbday.rollback
1052+
return roll_func
10451053

10461054
@cache_readonly
10471055
def m_offset(self):
10481056
if self._prefix.endswith('S'):
1049-
# MonthBegin:
1050-
return MonthBegin(n=1, normalize=self.normalize)
1057+
# MonthBegin
1058+
moff = MonthBegin(n=1, normalize=False)
10511059
else:
10521060
# MonthEnd
1053-
return MonthEnd(n=1, normalize=self.normalize)
1061+
moff = MonthEnd(n=1, normalize=False)
1062+
return moff
10541063

1055-
1056-
class CustomBusinessMonthEnd(_CustomBusinessMonth):
1057-
__doc__ = _CustomBusinessMonth.__doc__.replace('[BEGIN/END]', 'end')
1058-
_prefix = 'CBM'
1064+
@cache_readonly
1065+
def month_roll(self):
1066+
"""Define default roll function to be called in apply method"""
1067+
if self._prefix.endswith('S'):
1068+
# MonthBegin
1069+
roll_func = self.m_offset.rollback
1070+
else:
1071+
# MonthEnd
1072+
roll_func = self.m_offset.rollforward
1073+
return roll_func
10591074

10601075
@apply_wraps
10611076
def apply(self, other):
10621077
# First move to month offset
1063-
cur_mend = self.m_offset.rollforward(other)
1078+
cur_month_offset_date = self.month_roll(other)
10641079

10651080
# Find this custom month offset
1066-
compare_date = self.cbday.rollback(cur_mend)
1067-
n = liboffsets.roll_monthday(other, self.n, compare_date)
1081+
compare_date = self.cbday_roll(cur_month_offset_date)
1082+
n = liboffsets.roll_convention(other.day, self.n, compare_date.day)
10681083

1069-
new = cur_mend + n * self.m_offset
1070-
result = self.cbday.rollback(new)
1084+
new = cur_month_offset_date + n * self.m_offset
1085+
result = self.cbday_roll(new)
10711086
return result
10721087

10731088

1089+
class CustomBusinessMonthEnd(_CustomBusinessMonth):
1090+
__doc__ = _CustomBusinessMonth.__doc__.replace('[BEGIN/END]', 'end')
1091+
_prefix = 'CBM'
1092+
1093+
10741094
class CustomBusinessMonthBegin(_CustomBusinessMonth):
10751095
__doc__ = _CustomBusinessMonth.__doc__.replace('[BEGIN/END]', 'beginning')
10761096
_prefix = 'CBMS'
10771097

1078-
@apply_wraps
1079-
def apply(self, other):
1080-
# First move to month offset
1081-
cur_mbegin = self.m_offset.rollback(other)
1082-
1083-
# Find this custom month offset
1084-
compare_date = self.cbday.rollforward(cur_mbegin)
1085-
n = liboffsets.roll_monthday(other, self.n, compare_date)
1086-
1087-
new = cur_mbegin + n * self.m_offset
1088-
result = self.cbday.rollforward(new)
1089-
return result
1090-
10911098

10921099
# ---------------------------------------------------------------------
10931100
# Semi-Month Based Offset Classes

0 commit comments

Comments
 (0)