diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 846d863910b4c..32c98fbf9d655 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -610,6 +610,7 @@ Groupby/resample/rolling - 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`) - 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`) - Bug in :meth:`DataFrameGroupBy.apply` with ``as_index=False`` that was returning :class:`MultiIndex` instead of returning :class:`Index`. (:issue:`58291`) +- Bug in :meth:`DataFrameGroupBy.cumsum` and :meth:`DataFrameGroupBy.cumprod` where ``numeric_only`` parameter was passed indirectly through kwargs instead of passing directly. (:issue:`58811`) - Bug in :meth:`DataFrameGroupBy.cumsum` where it did not return the correct dtype when the label contained ``None``. (:issue:`58811`) - Bug in :meth:`DataFrameGroupby.transform` and :meth:`SeriesGroupby.transform` with a reducer and ``observed=False`` that coerces dtype to float when there are unobserved categories. (:issue:`55326`) - Bug in :meth:`Rolling.apply` where the applied function could be called on fewer than ``min_period`` periods if ``method="table"``. (:issue:`58868`) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 1a3a32375be54..b288dad63179f 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -4682,12 +4682,14 @@ def rank( @final @Substitution(name="groupby") @Substitution(see_also=_common_see_also) - def cumprod(self, *args, **kwargs) -> NDFrameT: + def cumprod(self, numeric_only: bool = False, *args, **kwargs) -> NDFrameT: """ Cumulative product for each group. Parameters ---------- + numeric_only : bool, default False + Include only float, int, boolean columns. *args : tuple Positional arguments to be passed to `func`. **kwargs : dict @@ -4735,18 +4737,20 @@ def cumprod(self, *args, **kwargs) -> NDFrameT: horse 16 10 bull 6 9 """ - nv.validate_groupby_func("cumprod", args, kwargs, ["numeric_only", "skipna"]) - return self._cython_transform("cumprod", **kwargs) + nv.validate_groupby_func("cumprod", args, kwargs, ["skipna"]) + return self._cython_transform("cumprod", numeric_only, **kwargs) @final @Substitution(name="groupby") @Substitution(see_also=_common_see_also) - def cumsum(self, *args, **kwargs) -> NDFrameT: + def cumsum(self, numeric_only: bool = False, *args, **kwargs) -> NDFrameT: """ Cumulative sum for each group. Parameters ---------- + numeric_only : bool, default False + Include only float, int, boolean columns. *args : tuple Positional arguments to be passed to `func`. **kwargs : dict @@ -4794,8 +4798,8 @@ def cumsum(self, *args, **kwargs) -> NDFrameT: gorilla 10 7 lion 6 9 """ - nv.validate_groupby_func("cumsum", args, kwargs, ["numeric_only", "skipna"]) - return self._cython_transform("cumsum", **kwargs) + nv.validate_groupby_func("cumsum", args, kwargs, ["skipna"]) + return self._cython_transform("cumsum", numeric_only, **kwargs) @final @Substitution(name="groupby") diff --git a/pandas/tests/groupby/test_api.py b/pandas/tests/groupby/test_api.py index 33b39bad4ab81..013b308cd14cd 100644 --- a/pandas/tests/groupby/test_api.py +++ b/pandas/tests/groupby/test_api.py @@ -185,7 +185,7 @@ def test_frame_consistency(groupby_func): elif groupby_func in ("cummax", "cummin"): exclude_expected = {"axis", "skipna", "args"} elif groupby_func in ("cumprod", "cumsum"): - exclude_expected = {"axis", "skipna", "numeric_only"} + exclude_expected = {"axis", "skipna"} elif groupby_func in ("pct_change",): exclude_expected = {"kwargs"} elif groupby_func in ("rank",): @@ -245,6 +245,7 @@ def test_series_consistency(request, groupby_func): exclude_result = {"numeric_only"} elif groupby_func in ("cumprod", "cumsum"): exclude_expected = {"skipna"} + exclude_result = {"numeric_only"} elif groupby_func in ("pct_change",): exclude_expected = {"kwargs"} elif groupby_func in ("rank",):