diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index 9d330cf3fdf2d..36b1cb7b6d5c5 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -90,6 +90,8 @@ Performance Improvements Bug Fixes ~~~~~~~~~ +- Fixes regression in 0.20, :func:`Series.aggregate` and :func:`DataFrame.aggregate` allow dictionaries as return values again (:issue:`16741`) + Conversion ^^^^^^^^^^ diff --git a/pandas/_libs/src/reduce.pyx b/pandas/_libs/src/reduce.pyx index 2bba07256305a..3ce94022e586b 100644 --- a/pandas/_libs/src/reduce.pyx +++ b/pandas/_libs/src/reduce.pyx @@ -419,7 +419,7 @@ cdef class SeriesGrouper: cdef inline _extract_result(object res): """ extract the result object, it might be a 0-dim ndarray or a len-1 0-dim, or a scalar """ - if hasattr(res, 'values'): + if hasattr(res, 'values') and isinstance(res.values, np.ndarray): res = res.values if not np.isscalar(res): if isinstance(res, np.ndarray): diff --git a/pandas/tests/groupby/test_aggregate.py b/pandas/tests/groupby/test_aggregate.py index b578a6efb0034..efc833575843c 100644 --- a/pandas/tests/groupby/test_aggregate.py +++ b/pandas/tests/groupby/test_aggregate.py @@ -611,6 +611,16 @@ def test_cython_agg_frame_columns(self): df.groupby(level=0, axis='columns').mean() df.groupby(level=0, axis='columns').mean() + def test_cython_agg_return_dict(self): + # GH 16741 + ts = self.df.groupby('A')['B'].agg( + lambda x: x.value_counts().to_dict()) + expected = Series([{'two': 1, 'one': 1, 'three': 1}, + {'two': 2, 'one': 2, 'three': 1}], + index=Index(['bar', 'foo'], name='A'), + name='B') + assert_series_equal(ts, expected) + def test_cython_fail_agg(self): dr = bdate_range('1/1/2000', periods=50) ts = Series(['A', 'B', 'C', 'D', 'E'] * 10, index=dr)