Skip to content

Fixed Issue Preventing Agg on RollingGroupBy Objects #21323

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 12 commits into from
Sep 26, 2018
Merged
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.24.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ Plotting
Groupby/Resample/Rolling
^^^^^^^^^^^^^^^^^^^^^^^^

-
- :func:`RollingGroupby.agg` and :func:`ExpandingGroupby.agg` now support multiple aggregation functions as parameters (:issue:`15072`)
-
-

Expand Down
8 changes: 7 additions & 1 deletion pandas/core/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,14 @@ def _gotitem(self, key, ndim, subset=None):
# with the same groupby
kwargs = dict([(attr, getattr(self, attr))
for attr in self._attributes])

Copy link
Contributor

Choose a reason for hiding this comment

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

minor, but can you put the comments before the try (and consolidate them into 1)

try:
groupby = self._groupby[key] # get slice of frame
except Exception:
Copy link
Member Author

Choose a reason for hiding this comment

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

Ideally would catch something more descriptive than an Exception, but that is all that gets raised:

raise Exception('Column(s) {selection} already selected'

Maybe an AttributeError would be more appropriate?

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah see if u can catch something more specific bere

groupby = self._groupby # working with a Series

self = self.__class__(subset,
groupby=self._groupby[key],
groupby=groupby,
parent=self,
**kwargs)
self._reset_cache()
Expand Down
47 changes: 47 additions & 0 deletions pandas/tests/test_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,53 @@ def test_preserve_metadata(self):
assert s2.name == 'foo'
assert s3.name == 'foo'

@pytest.mark.parametrize("func,window_size,expected_vals", [
('rolling', 2, [[np.nan, np.nan, np.nan, np.nan],
[15., 20., 25., 20.],
[25., 30., 35., 30.],
[np.nan, np.nan, np.nan, np.nan],
[20., 30., 35., 30.],
[35., 40., 60., 40.],
[60., 80., 85., 80]]),
('expanding', None, [[10., 10., 20., 20.],
[15., 20., 25., 20.],
[20., 30., 30., 20.],
[10., 10., 30., 30.],
[20., 30., 35., 30.],
[26.666667, 40., 50., 30.],
[40., 80., 60., 30.]])])
def test_multiple_agg_funcs(self, func, window_size, expected_vals):
# GH 15072
df = pd.DataFrame([
['A', 10, 20],
['A', 20, 30],
['A', 30, 40],
['B', 10, 30],
['B', 30, 40],
['B', 40, 80],
['B', 80, 90]], columns=['stock', 'low', 'high'])

f = getattr(df.groupby('stock'), func)
if window_size:
window = f(window_size)
else:
window = f()

index = pd.MultiIndex.from_tuples([
('A', 0), ('A', 1), ('A', 2),
('B', 3), ('B', 4), ('B', 5), ('B', 6)], names=['stock', None])
columns = pd.MultiIndex.from_tuples([
('low', 'mean'), ('low', 'max'), ('high', 'mean'),
('high', 'min')])
expected = pd.DataFrame(expected_vals, index=index, columns=columns)

result = window.agg({
'low': ['mean', 'max'],
'high': ['mean', 'min']
})

tm.assert_frame_equal(result, expected)


class TestWindow(Base):

Expand Down