diff --git a/doc/source/whatsnew/v0.16.1.txt b/doc/source/whatsnew/v0.16.1.txt index b80e341d4156a..a2e6b59646724 100644 --- a/doc/source/whatsnew/v0.16.1.txt +++ b/doc/source/whatsnew/v0.16.1.txt @@ -99,11 +99,10 @@ Bug Fixes - Bug in ``transform`` causing length mismatch when null entries were present and a fast aggregator was being used (:issue:`9697`) - - Bug in ``equals`` causing false negatives when block order differed (:issue:`9330`) - - Bug in ``DataFrame`` slicing may not retain metadata (:issue:`9776`) - Bug where ``TimdeltaIndex`` were not properly serialized in fixed ``HDFStore`` (:issue:`9635`) +- Fixed bug in ``groupby.apply()`` that would raise an error the user passed function either returned nothing or only returned values of ``None``. (:issue:`9685`) - Bug in plotting continuously using ``secondary_y`` may not show legend properly. (:issue:`9610`, :issue:`9779`) diff --git a/pandas/core/groupby.py b/pandas/core/groupby.py index 6d98b3b99021b..034e8298a844c 100644 --- a/pandas/core/groupby.py +++ b/pandas/core/groupby.py @@ -2808,7 +2808,12 @@ def _wrap_applied_output(self, keys, values, not_indexed_same=False): # make Nones an empty object if com._count_not_none(*values) != len(values): - v = next(v for v in values if v is not None) + try: + v = next(v for v in values if v is not None) + except StopIteration: + # If all values are None, then this will throw an error. + # We'd prefer it return an empty dataframe. + return DataFrame() if v is None: return DataFrame() elif isinstance(v, NDFrame): diff --git a/pandas/tests/test_groupby.py b/pandas/tests/test_groupby.py index e7001eb09f20c..a7af535034852 100644 --- a/pandas/tests/test_groupby.py +++ b/pandas/tests/test_groupby.py @@ -5053,6 +5053,17 @@ def test_groupby_categorical_two_columns(self): "C3":[nan,nan,nan,nan, 10,100,nan,nan, nan,nan,200,34]}, index=idx) tm.assert_frame_equal(res, exp) + def test_groupby_apply_all_none(self): + # Tests to make sure no errors if apply function returns all None + # values. Issue 9684. + test_df = DataFrame({'groups': [0,0,1,1], 'random_vars': [8,7,4,5]}) + + def test_func(x): + pass + result = test_df.groupby('groups').apply(test_func) + expected = DataFrame() + tm.assert_frame_equal(result, expected) + def assert_fp_equal(a, b): assert (np.abs(a - b) < 1e-12).all()