Skip to content

DEPR: deprecate axis keyword in GroupBy methods #52018

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

Merged
merged 2 commits into from
Mar 17, 2023
Merged
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/v2.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ Deprecations
- Deprecated passing a :class:`DataFrame` to :meth:`DataFrame.from_records`, use :meth:`DataFrame.set_index` or :meth:`DataFrame.drop` instead (:issue:`51353`)
- Deprecated accepting slices in :meth:`DataFrame.take`, call ``obj[slicer]`` or pass a sequence of integers instead (:issue:`51539`)
- Deprecated 'method', 'limit', and 'fill_axis' keywords in :meth:`DataFrame.align` and :meth:`Series.align`, explicitly call ``fillna`` on the alignment results instead (:issue:`51856`)
- Deprecated the 'axis' keyword in :meth:`.GroupBy.idxmax`, :meth:`.GroupBy.idxmin`, :meth:`.GroupBy.fillna`, :meth:`.GroupBy.take`, :meth:`.GroupBy.skew`, :meth:`.GroupBy.rank`, :meth:`.GroupBy.cumprod`, :meth:`.GroupBy.cumsum`, :meth:`.GroupBy.cummax`, :meth:`.GroupBy.cummin`, :meth:`.GroupBy.pct_change`, :meth:`GroupBy.diff`, :meth:`.GroupBy.shift`, and :meth:`DataFrameGroupBy.corrwith`; for ``axis=1`` operate on the underlying :class:`DataFrame` instead (:issue:`50405`, :issue:`51046`)
-

.. ---------------------------------------------------------------------------
Expand Down
21 changes: 20 additions & 1 deletion pandas/core/apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,11 @@ def apply_str(self) -> DataFrame | Series:

obj = self.obj

from pandas.core.groupby.generic import (
DataFrameGroupBy,
SeriesGroupBy,
)

# Support for `frame.transform('method')`
# Some methods (shift, etc.) require the axis argument, others
# don't, so inspect and insert if necessary.
Expand All @@ -492,7 +497,21 @@ def apply_str(self) -> DataFrame | Series:
):
raise ValueError(f"Operation {f} does not support axis=1")
if "axis" in arg_names:
self.kwargs["axis"] = self.axis
if isinstance(obj, (SeriesGroupBy, DataFrameGroupBy)):
# Try to avoid FutureWarning for deprecated axis keyword;
# If self.axis matches the axis we would get by not passing
# axis, we safely exclude the keyword.

default_axis = 0
if f in ["idxmax", "idxmin"]:
# DataFrameGroupBy.idxmax, idxmin axis defaults to self.axis,
# whereas other axis keywords default to 0
default_axis = self.obj.axis

if default_axis != self.axis:
self.kwargs["axis"] = self.axis
else:
self.kwargs["axis"] = self.axis
return self._try_aggregate_string_function(obj, f, *self.args, **self.kwargs)

def apply_multiple(self) -> DataFrame | Series:
Expand Down
72 changes: 59 additions & 13 deletions pandas/core/groupby/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ def fillna(
self,
value: object | ArrayLike | None = None,
method: FillnaOptions | None = None,
axis: Axis | None = None,
axis: Axis | None | lib.NoDefault = lib.no_default,
inplace: bool = False,
limit: int | None = None,
downcast: dict | None = None,
Expand All @@ -838,6 +838,11 @@ def fillna(
``'bfill'`` will use next valid observation to fill the gap.
axis : {0 or 'index', 1 or 'columns'}
Unused, only for compatibility with :meth:`DataFrameGroupBy.fillna`.

.. deprecated:: 2.1.0
For axis=1, operate on the underlying object instead. Otherwise
the axis keyword is not necessary.

inplace : bool, default False
Broken. Do not set to True.
limit : int, default None
Expand Down Expand Up @@ -919,7 +924,7 @@ def fillna(
def take(
self,
indices: TakeIndexer,
axis: Axis = 0,
axis: Axis | lib.NoDefault = lib.no_default,
**kwargs,
) -> Series:
"""
Expand All @@ -941,6 +946,11 @@ def take(
The axis on which to select elements. ``0`` means that we are
selecting rows, ``1`` means that we are selecting columns.
For `SeriesGroupBy` this parameter is unused and defaults to 0.

.. deprecated:: 2.1.0
For axis=1, operate on the underlying object instead. Otherwise
the axis keyword is not necessary.

**kwargs
For compatibility with :meth:`numpy.take`. Has no effect on the
output.
Expand Down Expand Up @@ -1016,6 +1026,10 @@ def skew(
Axis for the function to be applied on.
This parameter is only for compatibility with DataFrame and is unused.

.. deprecated:: 2.1.0
For axis=1, operate on the underlying object instead. Otherwise
the axis keyword is not necessary.

skipna : bool, default True
Exclude NA/null values when computing the result.

Expand Down Expand Up @@ -1095,12 +1109,16 @@ def nsmallest(
return result

@doc(Series.idxmin.__doc__)
def idxmin(self, axis: Axis = 0, skipna: bool = True) -> Series:
def idxmin(
self, axis: Axis | lib.NoDefault = lib.no_default, skipna: bool = True
) -> Series:
result = self._op_via_apply("idxmin", axis=axis, skipna=skipna)
return result.astype(self.obj.index.dtype) if result.empty else result

@doc(Series.idxmax.__doc__)
def idxmax(self, axis: Axis = 0, skipna: bool = True) -> Series:
def idxmax(
self, axis: Axis | lib.NoDefault = lib.no_default, skipna: bool = True
) -> Series:
result = self._op_via_apply("idxmax", axis=axis, skipna=skipna)
return result.astype(self.obj.index.dtype) if result.empty else result

Expand Down Expand Up @@ -1922,7 +1940,7 @@ def nunique(self, dropna: bool = True) -> DataFrame:

def idxmax(
self,
axis: Axis | None = None,
axis: Axis | None | lib.NoDefault = lib.no_default,
skipna: bool = True,
numeric_only: bool = False,
) -> DataFrame:
Expand All @@ -1939,6 +1957,10 @@ def idxmax(

.. versionchanged:: 2.0.0

.. deprecated:: 2.1.0
For axis=1, operate on the underlying object instead. Otherwise
the axis keyword is not necessary.

skipna : bool, default True
Exclude NA/null values. If an entire row/column is NA, the result
will be NA.
Expand Down Expand Up @@ -1994,7 +2016,12 @@ def idxmax(
Beef co2_emissions
dtype: object
"""
if axis is None:
if axis is not lib.no_default:
if axis is None:
axis = self.axis
axis = self.obj._get_axis_number(axis)
self._deprecate_axis(axis, "idxmax")
else:
axis = self.axis

def func(df):
Expand All @@ -2008,7 +2035,7 @@ def func(df):

def idxmin(
self,
axis: Axis | None = None,
axis: Axis | None | lib.NoDefault = lib.no_default,
skipna: bool = True,
numeric_only: bool = False,
) -> DataFrame:
Expand All @@ -2025,6 +2052,10 @@ def idxmin(

.. versionchanged:: 2.0.0

.. deprecated:: 2.1.0
For axis=1, operate on the underlying object instead. Otherwise
the axis keyword is not necessary.

skipna : bool, default True
Exclude NA/null values. If an entire row/column is NA, the result
will be NA.
Expand Down Expand Up @@ -2080,7 +2111,12 @@ def idxmin(
Beef consumption
dtype: object
"""
if axis is None:
if axis is not lib.no_default:
if axis is None:
axis = self.axis
axis = self.obj._get_axis_number(axis)
self._deprecate_axis(axis, "idxmin")
else:
axis = self.axis

def func(df):
Expand Down Expand Up @@ -2211,7 +2247,7 @@ def fillna(
self,
value: Hashable | Mapping | Series | DataFrame = None,
method: FillnaOptions | None = None,
axis: Axis | None = None,
axis: Axis | None | lib.NoDefault = lib.no_default,
inplace: bool = False,
limit=None,
downcast=None,
Expand Down Expand Up @@ -2240,8 +2276,9 @@ def fillna(
:class:`DataFrameGroupBy` ``axis`` argument is ``1``, using ``axis=0``
or ``axis=1`` here will produce the same results.

.. deprecated:: 2.0.0
Use frame.T.groupby(...) instead.
.. deprecated:: 2.1.0
For axis=1, operate on the underlying object instead. Otherwise
the axis keyword is not necessary.

inplace : bool, default False
Broken. Do not set to True.
Expand Down Expand Up @@ -2345,7 +2382,7 @@ def fillna(
def take(
self,
indices: TakeIndexer,
axis: Axis | None = 0,
axis: Axis | None | lib.NoDefault = lib.no_default,
**kwargs,
) -> DataFrame:
"""
Expand All @@ -2366,6 +2403,11 @@ def take(
axis : {0 or 'index', 1 or 'columns', None}, default 0
The axis on which to select elements. ``0`` means that we are
selecting rows, ``1`` means that we are selecting columns.

.. deprecated:: 2.1.0
For axis=1, operate on the underlying object instead. Otherwise
the axis keyword is not necessary.

**kwargs
For compatibility with :meth:`numpy.take`. Has no effect on the
output.
Expand Down Expand Up @@ -2459,6 +2501,10 @@ def skew(

.. versionadded:: 2.0.0

.. deprecated:: 2.1.0
For axis=1, operate on the underlying object instead. Otherwise
the axis keyword is not necessary.

skipna : bool, default True
Exclude NA/null values when computing the result.

Expand Down Expand Up @@ -2598,7 +2644,7 @@ def dtypes(self) -> Series:
def corrwith(
self,
other: DataFrame | Series,
axis: Axis = 0,
axis: Axis | lib.NoDefault = lib.no_default,
drop: bool = False,
method: CorrelationMethod = "pearson",
numeric_only: bool = False,
Expand Down
Loading