From 64804ff785f302dc0b1e07f688362da26e32315c Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Fri, 30 Sep 2022 16:18:55 +0200 Subject: [PATCH] REGR: fix df.apply with keyword non-zero axis (#48797) --- doc/source/whatsnew/v1.5.1.rst | 1 + pandas/core/apply.py | 7 +++++- pandas/tests/apply/test_frame_apply.py | 35 ++++++++++++++++++++++++++ pandas/tests/groupby/test_any_all.py | 22 ---------------- 4 files changed, 42 insertions(+), 23 deletions(-) diff --git a/doc/source/whatsnew/v1.5.1.rst b/doc/source/whatsnew/v1.5.1.rst index b810adde37d86..f58e10a701740 100644 --- a/doc/source/whatsnew/v1.5.1.rst +++ b/doc/source/whatsnew/v1.5.1.rst @@ -82,6 +82,7 @@ Fixed regressions - Fixed regression in :meth:`DataFrame.fillna` replacing wrong values for ``datetime64[ns]`` dtype and ``inplace=True`` (:issue:`48863`) - Fixed :meth:`.DataFrameGroupBy.size` not returning a Series when ``axis=1`` (:issue:`48738`) - Fixed Regression in :meth:`DataFrameGroupBy.apply` when user defined function is called on an empty dataframe (:issue:`47985`) +- Fixed regression in :meth:`DataFrame.apply` when passing non-zero ``axis`` via keyword argument (:issue:`48656`) - .. --------------------------------------------------------------------------- diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 7a7050ea8bad7..7c2cb1455995b 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -550,7 +550,12 @@ def apply_str(self) -> DataFrame | Series: func = getattr(obj, f, None) if callable(func): sig = inspect.getfullargspec(func) - if "axis" in sig.args: + arg_names = (*sig.args, *sig.kwonlyargs) + if self.axis != 0 and ( + "axis" not in arg_names or f in ("corrwith", "mad", "skew") + ): + raise ValueError(f"Operation {f} does not support axis=1") + elif "axis" in arg_names: self.kwargs["axis"] = self.axis elif self.axis != 0: raise ValueError(f"Operation {f} does not support axis=1") diff --git a/pandas/tests/apply/test_frame_apply.py b/pandas/tests/apply/test_frame_apply.py index d2882f46d25bf..3bcb7d964fad1 100644 --- a/pandas/tests/apply/test_frame_apply.py +++ b/pandas/tests/apply/test_frame_apply.py @@ -1604,3 +1604,38 @@ def test_unique_agg_type_is_series(test, constant): result = df1.agg(aggregation) tm.assert_series_equal(result, expected) + + +def test_any_non_keyword_deprecation(): + df = DataFrame({"A": [1, 2], "B": [0, 2], "C": [0, 0]}) + msg = ( + "In a future version of pandas all arguments of " + "DataFrame.any and Series.any will be keyword-only." + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + result = df.any("index", None) + expected = Series({"A": True, "B": True, "C": False}) + tm.assert_series_equal(result, expected) + + s = Series([False, False, False]) + msg = ( + "In a future version of pandas all arguments of " + "DataFrame.any and Series.any will be keyword-only." + ) + with tm.assert_produces_warning(FutureWarning, match=msg): + result = s.any("index") + expected = False + tm.assert_equal(result, expected) + + +def test_any_apply_keyword_non_zero_axis_regression(): + # https://github.com/pandas-dev/pandas/issues/48656 + df = DataFrame({"A": [1, 2, 0], "B": [0, 2, 0], "C": [0, 0, 0]}) + expected = Series([True, True, False]) + tm.assert_series_equal(df.any(axis=1), expected) + + result = df.apply("any", axis=1) + tm.assert_series_equal(result, expected) + + result = df.apply("any", 1) + tm.assert_series_equal(result, expected) diff --git a/pandas/tests/groupby/test_any_all.py b/pandas/tests/groupby/test_any_all.py index 784ff1069e7ff..3f61a4ece66c0 100644 --- a/pandas/tests/groupby/test_any_all.py +++ b/pandas/tests/groupby/test_any_all.py @@ -61,28 +61,6 @@ def test_any(): tm.assert_frame_equal(result, expected) -def test_any_non_keyword_deprecation(): - df = DataFrame({"A": [1, 2], "B": [0, 2], "C": [0, 0]}) - msg = ( - "In a future version of pandas all arguments of " - "DataFrame.any and Series.any will be keyword-only." - ) - with tm.assert_produces_warning(FutureWarning, match=msg): - result = df.any("index", None) - expected = Series({"A": True, "B": True, "C": False}) - tm.assert_series_equal(result, expected) - - s = Series([False, False, False]) - msg = ( - "In a future version of pandas all arguments of " - "DataFrame.any and Series.any will be keyword-only." - ) - with tm.assert_produces_warning(FutureWarning, match=msg): - result = s.any("index") - expected = False - tm.assert_equal(result, expected) - - @pytest.mark.parametrize("bool_agg_func", ["any", "all"]) def test_bool_aggs_dup_column_labels(bool_agg_func): # 21668