Skip to content

Commit ca40b48

Browse files
committed
BUG/ENH: week-of-month time rule inference. close #2140
1 parent 40ed7d9 commit ca40b48

File tree

3 files changed

+27
-0
lines changed

3 files changed

+27
-0
lines changed

RELEASE.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pandas 0.9.1
3636

3737
**Improvements to existing features**
3838

39+
- Time rule inference for week-of-month (e.g. WOM-2FRI) rules (#2140)
3940
- Improve performance of datetime + business day offset with large number of
4041
offset periods
4142
- Improve HTML display of DataFrame objects with hierarchical columns

pandas/tseries/frequencies.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import numpy as np
55

6+
from pandas.core.algorithms import unique
67
from pandas.tseries.offsets import DateOffset
78
from pandas.util.decorators import cache_readonly
89
import pandas.tseries.offsets as offsets
@@ -890,6 +891,10 @@ def _infer_daily_rule(self):
890891
if self.day_deltas == [1, 3]:
891892
return 'B'
892893

894+
wom_rule = self._get_wom_rule()
895+
if wom_rule:
896+
return wom_rule
897+
893898
def _get_annual_rule(self):
894899
if len(self.ydiffs) > 1:
895900
return None
@@ -919,6 +924,20 @@ def _get_monthly_rule(self):
919924
return {'cs': 'MS', 'bs': 'BMS',
920925
'ce': 'M', 'be': 'BM'}.get(pos_check)
921926

927+
def _get_wom_rule(self):
928+
wdiffs = unique(np.diff(self.index.week))
929+
if not lib.ismember(wdiffs, set([4, 5])).all():
930+
return None
931+
932+
weekdays = unique(self.index.weekday)
933+
if len(weekdays) > 1:
934+
return None
935+
936+
# get which week
937+
week = (self.index[0].day - 1) // 7 + 1
938+
wd = _weekday_rule_aliases[weekdays[0]]
939+
940+
return 'WOM-%d%s' % (week, wd)
922941

923942
import pandas.core.algorithms as algos
924943

pandas/tseries/tests/test_frequencies.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ def test_weekly(self):
142142
for day in days:
143143
self._check_generated_range('1/1/2000', 'W-%s' % day)
144144

145+
def test_week_of_month(self):
146+
days = ['MON', 'TUE', 'WED', 'THU', 'FRI']
147+
148+
for day in days:
149+
for i in range(1, 5):
150+
self._check_generated_range('1/1/2000', 'WOM-%d%s' % (i, day))
151+
145152
def test_monthly(self):
146153
self._check_generated_range('1/1/2000', 'M')
147154

0 commit comments

Comments
 (0)