Skip to content

Commit

Permalink
Fixes GH16624
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Gleave authored and Adam Gleave committed Jun 12, 2017
1 parent b72519e commit 12927e0
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 5 deletions.
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.20.3.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Plotting
Groupby/Resample/Rolling
^^^^^^^^^^^^^^^^^^^^^^^^


- Bug in ``infer_freq`` causing indices with 2-day gaps during the working week to be wrongly inferred as business daily (:issue:`16624`)

Sparse
^^^^^^
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/timedeltas/test_timedelta.py
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ class TestSlicing(object):

def test_timedelta(self):
# this is valid too
index = date_range('1/1/2000', periods=50, freq='B')
index = date_range('1/1/2000', periods=50, freq='D')
shifted = index + timedelta(1)
back = shifted + timedelta(-1)
assert tm.equalContents(index, back)
Expand Down
7 changes: 6 additions & 1 deletion pandas/tests/tseries/test_frequencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,9 +504,14 @@ def test_raise_if_too_few(self):
pytest.raises(ValueError, frequencies.infer_freq, index)

def test_business_daily(self):
index = _dti(['12/31/1998', '1/3/1999', '1/4/1999'])
index = _dti(['01/01/1999', '1/4/1999', '1/5/1999'])
assert frequencies.infer_freq(index) == 'B'

def test_business_daily_look_alike(self):
# 'weekend' (2-day gap) in wrong place
index = _dti(['12/31/1998', '1/3/1999', '1/4/1999'])
assert frequencies.infer_freq(index) is None

def test_day(self):
self._check_tick(timedelta(1), 'D')

Expand Down
14 changes: 12 additions & 2 deletions pandas/tseries/frequencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,7 @@ def _infer_daily_rule(self):
else:
return _maybe_add_count('D', days)

# Business daily. Maybe
if self.day_deltas == [1, 3]:
if self._is_business_daily():
return 'B'

wom_rule = self._get_wom_rule()
Expand Down Expand Up @@ -1012,6 +1011,17 @@ def _get_monthly_rule(self):
return {'cs': 'MS', 'bs': 'BMS',
'ce': 'M', 'be': 'BM'}.get(pos_check)

def _is_business_daily(self):
if self.day_deltas != [1, 3]: # quick check: cannot be business daily
return False
# probably business daily, but need to confirm
first_weekday = self.index[0].weekday()
shifts = np.diff(np.asarray(self.index).view('i8'))
shifts = np.floor_divide(shifts, _ONE_DAY)
weekdays = np.mod(first_weekday + np.cumsum(shifts), 7)
return np.all(((weekdays == 0) & (shifts == 3)) |
((weekdays > 0) & (weekdays <= 4) & (shifts == 1)))

def _get_wom_rule(self):
# wdiffs = unique(np.diff(self.index.week))
# We also need -47, -49, -48 to catch index spanning year boundary
Expand Down

0 comments on commit 12927e0

Please sign in to comment.