Skip to content

Commit 2378141

Browse files
authored
BUG: Fix inconsistent returned objects when applying groupby aggregations (#61508)
* Wrapped return object * Added tests * Whatsnew * pre-commit
1 parent f31a4b1 commit 2378141

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ Groupby/resample/rolling
825825
- Bug in :meth:`DataFrame.resample` and :meth:`Series.resample` were not keeping the index name when the index had :class:`ArrowDtype` timestamp dtype (:issue:`61222`)
826826
- Bug in :meth:`DataFrame.resample` changing index type to :class:`MultiIndex` when the dataframe is empty and using an upsample method (:issue:`55572`)
827827
- Bug in :meth:`DataFrameGroupBy.agg` that raises ``AttributeError`` when there is dictionary input and duplicated columns, instead of returning a DataFrame with the aggregation of all duplicate columns. (:issue:`55041`)
828+
- Bug in :meth:`DataFrameGroupBy.agg` where applying a user-defined function to an empty DataFrame returned a Series instead of an empty DataFrame. (:issue:`61503`)
828829
- Bug in :meth:`DataFrameGroupBy.apply` and :meth:`SeriesGroupBy.apply` for empty data frame with ``group_keys=False`` still creating output index using group keys. (:issue:`60471`)
829830
- Bug in :meth:`DataFrameGroupBy.apply` that was returning a completely empty DataFrame when all return values of ``func`` were ``None`` instead of returning an empty DataFrame with the original columns and dtypes. (:issue:`57775`)
830831
- Bug in :meth:`DataFrameGroupBy.apply` with ``as_index=False`` that was returning :class:`MultiIndex` instead of returning :class:`Index`. (:issue:`58291`)

pandas/core/groupby/generic.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,11 +504,13 @@ def aggregate(self, func=None, *args, engine=None, engine_kwargs=None, **kwargs)
504504
# inference. We default to using the existing dtype.
505505
# xref GH#51445
506506
obj = self._obj_with_exclusions
507-
return self.obj._constructor(
508-
[],
509-
name=self.obj.name,
510-
index=self._grouper.result_index,
511-
dtype=obj.dtype,
507+
return self._wrap_aggregated_output(
508+
self.obj._constructor(
509+
[],
510+
name=self.obj.name,
511+
index=self._grouper.result_index,
512+
dtype=obj.dtype,
513+
)
512514
)
513515
return self._python_agg_general(func, *args, **kwargs)
514516

pandas/tests/groupby/aggregate/test_aggregate.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,3 +1807,20 @@ def test_groupby_aggregation_func_list_multi_index_duplicate_columns():
18071807
index=Index(["level1.1", "level1.2"]),
18081808
)
18091809
tm.assert_frame_equal(result, expected)
1810+
1811+
1812+
def test_groupby_aggregate_empty_builtin_sum():
1813+
df = DataFrame(columns=["Group", "Data"])
1814+
result = df.groupby(["Group"], as_index=False)["Data"].agg("sum")
1815+
expected = DataFrame(columns=["Group", "Data"])
1816+
tm.assert_frame_equal(result, expected)
1817+
1818+
1819+
def test_groupby_aggregate_empty_udf():
1820+
def func(x):
1821+
return sum(x)
1822+
1823+
df = DataFrame(columns=["Group", "Data"])
1824+
result = df.groupby(["Group"], as_index=False)["Data"].agg(func)
1825+
expected = DataFrame(columns=["Group", "Data"])
1826+
tm.assert_frame_equal(result, expected)

0 commit comments

Comments
 (0)