Skip to content

Commit 96b6cb2

Browse files
jbrockmendelyeshsurya
authored andcommitted
REF: avoid passing empty list to concat in groupby methods (pandas-dev#41231)
1 parent dd617b6 commit 96b6cb2

File tree

3 files changed

+33
-24
lines changed

3 files changed

+33
-24
lines changed

pandas/core/groupby/generic.py

+27-19
Original file line numberDiff line numberDiff line change
@@ -1754,11 +1754,16 @@ def _iterate_column_groupbys(self):
17541754
def _apply_to_column_groupbys(self, func) -> DataFrame:
17551755
from pandas.core.reshape.concat import concat
17561756

1757-
return concat(
1758-
(func(col_groupby) for _, col_groupby in self._iterate_column_groupbys()),
1759-
keys=self._selected_obj.columns,
1760-
axis=1,
1761-
)
1757+
columns = self._selected_obj.columns
1758+
results = [
1759+
func(col_groupby) for _, col_groupby in self._iterate_column_groupbys()
1760+
]
1761+
1762+
if not len(results):
1763+
# concat would raise
1764+
return DataFrame([], columns=columns, index=self.grouper.result_index)
1765+
else:
1766+
return concat(results, keys=columns, axis=1)
17621767

17631768
def count(self) -> DataFrame:
17641769
"""
@@ -1850,27 +1855,30 @@ def nunique(self, dropna: bool = True) -> DataFrame:
18501855
# Try to consolidate with normal wrapping functions
18511856

18521857
obj = self._obj_with_exclusions
1853-
axis_number = obj._get_axis_number(self.axis)
1854-
other_axis = int(not axis_number)
1855-
if axis_number == 0:
1858+
if self.axis == 0:
18561859
iter_func = obj.items
18571860
else:
18581861
iter_func = obj.iterrows
18591862

1860-
results = concat(
1861-
[
1862-
SeriesGroupBy(content, selection=label, grouper=self.grouper).nunique(
1863-
dropna
1864-
)
1865-
for label, content in iter_func()
1866-
],
1867-
axis=1,
1868-
)
1869-
results = cast(DataFrame, results)
1863+
res_list = [
1864+
SeriesGroupBy(content, selection=label, grouper=self.grouper).nunique(
1865+
dropna
1866+
)
1867+
for label, content in iter_func()
1868+
]
1869+
if res_list:
1870+
results = concat(res_list, axis=1)
1871+
results = cast(DataFrame, results)
1872+
else:
1873+
# concat would raise
1874+
results = DataFrame(
1875+
[], index=self.grouper.result_index, columns=obj.columns[:0]
1876+
)
18701877

1871-
if axis_number == 1:
1878+
if self.axis == 1:
18721879
results = results.T
18731880

1881+
other_axis = 1 - self.axis
18741882
results._get_axis(other_axis).names = obj._get_axis(other_axis).names
18751883

18761884
if not self.as_index:

pandas/core/resample.py

-5
Original file line numberDiff line numberDiff line change
@@ -450,11 +450,6 @@ def _groupby_and_aggregate(self, how, grouper=None, *args, **kwargs):
450450
elif "len(index) != len(labels)" in str(err):
451451
# raised in libgroupby validation
452452
pass
453-
elif "No objects to concatenate" in str(err):
454-
# raised in concat call
455-
# In tests this is reached via either
456-
# _apply_to_column_groupbys (ohlc) or DataFrameGroupBy.nunique
457-
pass
458453
else:
459454
raise
460455

pandas/tests/groupby/test_groupby.py

+6
Original file line numberDiff line numberDiff line change
@@ -2020,6 +2020,12 @@ def test_groupby_crash_on_nunique(axis):
20202020

20212021
tm.assert_frame_equal(result, expected)
20222022

2023+
# same thing, but empty columns
2024+
gb = df[[]].groupby(axis=axis_number, level=0)
2025+
res = gb.nunique()
2026+
exp = expected[[]]
2027+
tm.assert_frame_equal(res, exp)
2028+
20232029

20242030
def test_groupby_list_level():
20252031
# GH 9790

0 commit comments

Comments
 (0)