Skip to content

ENH: Accept no fields for groupby by #61168

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Other enhancements
- :meth:`DataFrame.cummin`, :meth:`DataFrame.cummax`, :meth:`DataFrame.cumprod` and :meth:`DataFrame.cumsum` methods now have a ``numeric_only`` parameter (:issue:`53072`)
- :meth:`DataFrame.ewm` now allows ``adjust=False`` when ``times`` is provided (:issue:`54328`)
- :meth:`DataFrame.fillna` and :meth:`Series.fillna` can now accept ``value=None``; for non-object dtype the corresponding NA value will be used (:issue:`57723`)
- :meth:`DataFrame.groupby` now accepts no fields for ``groupby`` by in :meth:`DataFrame.groupby` (:issue:`61160`)
- :meth:`DataFrame.pivot_table` and :func:`pivot_table` now allow the passing of keyword arguments to ``aggfunc`` through ``**kwargs`` (:issue:`57884`)
- :meth:`DataFrame.to_json` now encodes ``Decimal`` as strings instead of floats (:issue:`60698`)
- :meth:`Series.cummin` and :meth:`Series.cummax` now supports :class:`CategoricalDtype` (:issue:`52335`)
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -9153,8 +9153,8 @@ def groupby(
) -> DataFrameGroupBy:
from pandas.core.groupby.generic import DataFrameGroupBy

if level is None and by is None:
raise TypeError("You have to supply one of 'by' and 'level'")
if level is None and (by is None or by == []):
by = Series(0, index=self.index)

return DataFrameGroupBy(
obj=self,
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -1973,8 +1973,8 @@ def groupby(
) -> SeriesGroupBy:
from pandas.core.groupby.generic import SeriesGroupBy

if level is None and by is None:
raise TypeError("You have to supply one of 'by' and 'level'")
if level is None and (by is None or by == []):
by = Series(0, index=self.index)
if not as_index:
raise TypeError("as_index=False only valid with DataFrame")

Expand Down
40 changes: 34 additions & 6 deletions pandas/tests/groupby/test_grouping.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,17 +695,45 @@ def test_groupby_level_with_nas(self, sort):
expected = Series([6.0, 18.0], index=[0.0, 1.0])
tm.assert_series_equal(result, expected)

def test_groupby_without_by(self):
# GH 61160
df = DataFrame({"A": [1, 2, 3, 4], "B": [10, 20, 30, 40]})

# Test basic aggregation with no fields
result = df.groupby().sum()
expected = df.sum().to_frame().T
tm.assert_frame_equal(result, expected)

# Test with multiple aggregations
result = df.groupby().agg(["sum", "mean"])
expected = df.agg(["sum", "mean"])
tm.assert_frame_equal(result, expected)

# Test Series.groupby() without any fields
s = Series([1, 2, 3, 4])
result = s.groupby().sum()
expected = Series([10]) # Sum of the values
tm.assert_series_equal(result, expected)

# Test with conditional logic - should work with None/empty list
groupby_fields = None
result = df.groupby(groupby_fields).sum()
expected = df.sum().to_frame().T
tm.assert_frame_equal(result, expected)

result = df.groupby([]).sum()
tm.assert_frame_equal(result, expected)

def test_groupby_args(self, multiindex_dataframe_random_data):
# PR8618 and issue 8015
frame = multiindex_dataframe_random_data

msg = "You have to supply one of 'by' and 'level'"
with pytest.raises(TypeError, match=msg):
frame.groupby()
result = frame.groupby().sum()
expected = frame.sum().to_frame().T
tm.assert_frame_equal(result, expected)

msg = "You have to supply one of 'by' and 'level'"
with pytest.raises(TypeError, match=msg):
frame.groupby(by=None, level=None)
result = frame.groupby(by=None, level=None).sum()
tm.assert_frame_equal(result, expected)

@pytest.mark.parametrize(
"sort,labels",
Expand Down
Loading