Skip to content

Fix offset __inits__, apply_index dtypes #19142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Jan 12, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 5 additions & 32 deletions pandas/_libs/tslibs/offsets.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -290,27 +290,6 @@ class CacheableOffset(object):
_cacheable = True


class EndMixin(object):
# helper for vectorized offsets

def _end_apply_index(self, i, freq):
"""Offsets index to end of Period frequency"""

off = i.to_perioddelta('D')

base, mult = get_freq_code(freq)
base_period = i.to_period(base)
if self.n > 0:
# when adding, dates on end roll to next
roll = np.where(base_period.to_timestamp(how='end') == i - off,
self.n, self.n - 1)
else:
roll = self.n

base = (base_period + roll).to_timestamp(how='end')
return base + off


# ---------------------------------------------------------------------
# Base Classes

Expand Down Expand Up @@ -675,11 +654,8 @@ def shift_months(int64_t[:] dtindex, int months, object day=None):
months_to_roll = months
compare_day = get_firstbday(dts.year, dts.month)

if months_to_roll > 0 and dts.day < compare_day:
months_to_roll -= 1
elif months_to_roll <= 0 and dts.day > compare_day:
# as if rolled forward already
months_to_roll += 1
months_to_roll = roll_convention(dts.day, months_to_roll,
compare_day)

dts.year = year_add_months(dts, months_to_roll)
dts.month = month_add_months(dts, months_to_roll)
Expand All @@ -698,11 +674,8 @@ def shift_months(int64_t[:] dtindex, int months, object day=None):
months_to_roll = months
compare_day = get_lastbday(dts.year, dts.month)

if months_to_roll > 0 and dts.day < compare_day:
months_to_roll -= 1
elif months_to_roll <= 0 and dts.day > compare_day:
# as if rolled forward already
months_to_roll += 1
months_to_roll = roll_convention(dts.day, months_to_roll,
compare_day)

dts.year = year_add_months(dts, months_to_roll)
dts.month = month_add_months(dts, months_to_roll)
Expand Down Expand Up @@ -823,7 +796,7 @@ cpdef int get_day_of_month(datetime other, day_opt) except? -1:
raise ValueError(day_opt)


cpdef int roll_convention(int other, int n, int compare):
cpdef int roll_convention(int other, int n, int compare) nogil:
"""
Possibly increment or decrement the number of periods to shift
based on rollforward/rollbackward conventions.
Expand Down
35 changes: 26 additions & 9 deletions pandas/tseries/offsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
apply_index_wraps,
roll_yearday,
shift_month,
EndMixin,
BaseOffset)


Expand Down Expand Up @@ -1226,7 +1225,8 @@ def _get_roll(self, i, before_day_of_month, after_day_of_month):
return roll

def _apply_index_days(self, i, roll):
i += (roll % 2) * Timedelta(days=self.day_of_month).value
nanos = (roll % 2) * Timedelta(days=self.day_of_month).value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather

n = Timedelta((roll % 2) * Timedelta(days=self.day_of_month).value)
return i + n + Timedelta(days-1)

Copy link
Member Author

@jbrockmendel jbrockmendel Jan 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

roll is an array

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then pls add a doc-string (same below)

i += nanos.astype('timedelta64[ns]')
return i + Timedelta(days=-1)


Expand Down Expand Up @@ -1271,13 +1271,14 @@ def _get_roll(self, i, before_day_of_month, after_day_of_month):
return roll

def _apply_index_days(self, i, roll):
return i + (roll % 2) * Timedelta(days=self.day_of_month - 1).value
nanos = (roll % 2) * Timedelta(days=self.day_of_month - 1).value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

return i + nanos.astype('timedelta64[ns]')


# ---------------------------------------------------------------------
# Week-Based Offset Classes

class Week(EndMixin, DateOffset):
class Week(DateOffset):
"""
Weekly offset

Expand Down Expand Up @@ -1327,6 +1328,22 @@ def apply_index(self, i):
else:
return self._end_apply_index(i, self.freqstr)

def _end_apply_index(self, dtindex, freq):
"""Offsets index to end of Period frequency"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc-string

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

off = dtindex.to_perioddelta('D')

base_period = dtindex.to_period('W')
if self.n > 0:
# when adding, dates on end roll to next
normed = dtindex - off
roll = np.where(base_period.to_timestamp(how='end') == normed,
self.n, self.n - 1)
else:
roll = self.n

base = (base_period + roll).to_timestamp(how='end')
return base + off

def onOffset(self, dt):
if self.normalize and not _is_normalized(dt):
return False
Expand Down Expand Up @@ -1380,9 +1397,9 @@ class WeekOfMonth(_WeekOfMonthMixin, DateOffset):
Parameters
----------
n : int
week : {0, 1, 2, 3, ...}, default None
week : {0, 1, 2, 3, ...}, default 0
0 is 1st week of month, 1 2nd week, etc.
weekday : {0, 1, ..., 6}, default None
weekday : {0, 1, ..., 6}, default 0
0: Mondays
1: Tuesdays
2: Wednesdays
Expand All @@ -1394,7 +1411,7 @@ class WeekOfMonth(_WeekOfMonthMixin, DateOffset):
_prefix = 'WOM'
_adjust_dst = True

def __init__(self, n=1, normalize=False, week=None, weekday=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't break anything???

Copy link
Member Author

@jbrockmendel jbrockmendel Jan 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default kwargs raise ATM.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is the test for this? why isn't it raising currently?

def __init__(self, n=1, normalize=False, week=0, weekday=0):
self.n = self._validate_n(n)
self.normalize = normalize
self.weekday = weekday
Expand Down Expand Up @@ -1457,7 +1474,7 @@ class LastWeekOfMonth(_WeekOfMonthMixin, DateOffset):
Parameters
----------
n : int, default 1
weekday : {0, 1, ..., 6}, default None
weekday : {0, 1, ..., 6}, default 0
0: Mondays
1: Tuesdays
2: Wednesdays
Expand All @@ -1470,7 +1487,7 @@ class LastWeekOfMonth(_WeekOfMonthMixin, DateOffset):
_prefix = 'LWOM'
_adjust_dst = True

def __init__(self, n=1, normalize=False, weekday=None):
def __init__(self, n=1, normalize=False, weekday=0):
self.n = self._validate_n(n)
self.normalize = normalize
self.weekday = weekday
Expand Down