Skip to content

Commit 5831b8e

Browse files
committed
BUG: no need to validate monotonicity when groupby-rolling
closes pandas-dev#15130
1 parent 5cc98ea commit 5831b8e

File tree

3 files changed

+57
-14
lines changed

3 files changed

+57
-14
lines changed

doc/source/whatsnew/v0.20.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ Bug Fixes
392392

393393

394394

395-
395+
- Bug in ``.groupby(...).rolling(...)`` when the ``on`` is specified and using a ``DatetimeIndex`` (:issue:`15130`)
396396

397397

398398

pandas/core/window.py

+36-13
Original file line numberDiff line numberDiff line change
@@ -1025,19 +1025,8 @@ def validate(self):
10251025
if (self.is_datetimelike and
10261026
isinstance(self.window, (compat.string_types, DateOffset))):
10271027

1028-
# must be monotonic for on
1029-
if not self._on.is_monotonic:
1030-
formatted = self.on or 'index'
1031-
raise ValueError("{0} must be "
1032-
"monotonic".format(formatted))
1033-
1034-
from pandas.tseries.frequencies import to_offset
1035-
try:
1036-
freq = to_offset(self.window)
1037-
except (TypeError, ValueError):
1038-
raise ValueError("passed window {0} in not "
1039-
"compat with a datetimelike "
1040-
"index".format(self.window))
1028+
self._validate_monotonic()
1029+
freq = self._validate_freq()
10411030

10421031
# we don't allow center
10431032
if self.center:
@@ -1058,6 +1047,23 @@ def validate(self):
10581047
elif self.window < 0:
10591048
raise ValueError("window must be non-negative")
10601049

1050+
def _validate_monotonic(self):
1051+
""" validate on is monotonic """
1052+
if not self._on.is_monotonic:
1053+
formatted = self.on or 'index'
1054+
raise ValueError("{0} must be "
1055+
"monotonic".format(formatted))
1056+
1057+
def _validate_freq(self):
1058+
""" validate & return our freq """
1059+
from pandas.tseries.frequencies import to_offset
1060+
try:
1061+
return to_offset(self.window)
1062+
except (TypeError, ValueError):
1063+
raise ValueError("passed window {0} in not "
1064+
"compat with a datetimelike "
1065+
"index".format(self.window))
1066+
10611067
@Substitution(name='rolling')
10621068
@Appender(SelectionMixin._see_also_template)
10631069
@Appender(SelectionMixin._agg_doc)
@@ -1175,6 +1181,23 @@ class RollingGroupby(_GroupByMixin, Rolling):
11751181
def _constructor(self):
11761182
return Rolling
11771183

1184+
def _gotitem(self, key, ndim, subset=None):
1185+
1186+
# we are resetting the actual object here so our
1187+
# index is carried thru to the selected obj
1188+
# when we do the splitting for the groupby
1189+
if self.on is not None:
1190+
self._groupby.obj = self._groupby.obj.set_index(self._on)
1191+
self.on = None
1192+
return super(RollingGroupby, self)._gotitem(key, ndim, subset=subset)
1193+
1194+
def _validate_monotonic(self):
1195+
"""
1196+
validate on is monotonic;
1197+
we don't care for groupby.rolling
1198+
"""
1199+
pass
1200+
11781201

11791202
class Expanding(_Rolling_and_Expanding):
11801203
"""

pandas/tests/test_window.py

+20
Original file line numberDiff line numberDiff line change
@@ -3616,3 +3616,23 @@ def agg_by_day(x):
36163616
agg_by_day).reset_index(level=0, drop=True)
36173617

36183618
tm.assert_frame_equal(result, expected)
3619+
3620+
def test_groupby_monotonic(self):
3621+
3622+
# GH 15130
3623+
# we don't need to validate monotonicity when grouping
3624+
3625+
data = [
3626+
['David', '1/1/2015', 100], ['David', '1/5/2015', 500],
3627+
['David', '5/30/2015', 50], ['David', '7/25/2015', 50],
3628+
['Ryan', '1/4/2014', 100], ['Ryan', '1/19/2015', 500],
3629+
['Ryan', '3/31/2016', 50], ['Joe', '7/1/2015', 100],
3630+
['Joe', '9/9/2015', 500], ['Joe', '10/15/2015', 50]]
3631+
3632+
df = pd.DataFrame(data=data, columns=['name', 'date', 'amount'])
3633+
df['date'] = pd.to_datetime(df['date'])
3634+
3635+
expected = df.set_index('date').groupby('name').apply(
3636+
lambda x: x.rolling('180D')['amount'].sum())
3637+
result = df.groupby('name').rolling('180D', on='date')['amount'].sum()
3638+
tm.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)