From 18c24e231d0e2a82f40451025469c6873f596080 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Wed, 7 Oct 2020 13:15:22 -0400 Subject: [PATCH 1/3] REGR: Allow positional arguments in DataFrame.agg Although `DataFrame.agg` is documented as accepting `func, axis, *args, **kwargs` with `*args` and `**kwargs` passed to `func`, passing positional arguments raises a TypeError. The reason for this is that the internal call to `self._aggregate` uses a keyword argument (axis) before passing *args and `**kwargs`, and as such the first positional argument is always interpreted as a second specification of `axis`, which raises TypeError. Prior to commit 433c9007781080658553fbef1a4d0c2813b404c0, TypeErrors were being suppressed, falling back to `self.apply`, which in v1.1.0 turned into an error. This fixes issue GH-36948. --- pandas/core/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 29c63b030cdd5..87724078ff163 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -7406,7 +7406,7 @@ def aggregate(self, func=None, axis=0, *args, **kwargs): result = None try: - result, how = self._aggregate(func, axis=axis, *args, **kwargs) + result, how = self._aggregate(func, axis, *args, **kwargs) except TypeError as err: exc = TypeError( "DataFrame constructor called with " From 1fd760501ee84eab48aaf439566884960f0747c0 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Wed, 7 Oct 2020 13:50:00 -0400 Subject: [PATCH 2/3] Add test for DataFrame.agg with *args, **kwargs --- pandas/tests/frame/apply/test_frame_apply.py | 28 ++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pandas/tests/frame/apply/test_frame_apply.py b/pandas/tests/frame/apply/test_frame_apply.py index 5c6a47c57970b..598da9c52731e 100644 --- a/pandas/tests/frame/apply/test_frame_apply.py +++ b/pandas/tests/frame/apply/test_frame_apply.py @@ -1463,6 +1463,34 @@ def test_agg_cython_table_raises(self, df, func, expected, axis): with pytest.raises(expected, match=msg): df.agg(func, axis=axis) + @pytest.mark.parametrize("axis", [0, 1]) + @pytest.mark.parametrize( + "args, kwargs", + [ + ((1, 2, 3), {}), + ((8, 7, 15), {}), + ((1, 2), {}), + ((1,), {"b": 2}), + ((), {"a": 1, "b": 2}), + ((), {"a": 2, "b": 1}), + ((), {"a": 1, "b": 2, "c": 3}), + ], + ) + def test_agg_args_kwargs(self, axis, args, kwargs): + def f(x, a, b, c=3): + return x.sum() + (a + b) / c + + df = pd.DataFrame([[1, 2], [3, 4]]) + + if axis == 0: + expected = pd.Series([5.0, 7.0]) + else: + expected = pd.Series([4.0, 8.0]) + + result = df.agg(f, axis, *args, **kwargs) + + tm.assert_series_equal(result, expected) + @pytest.mark.parametrize("num_cols", [2, 3, 5]) def test_frequency_is_original(self, num_cols): # GH 22150 From 4a37cd348f5692734b21d4d6dad59c184c989fdd Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Thu, 8 Oct 2020 10:55:17 -0400 Subject: [PATCH 3/3] What's new entry --- doc/source/whatsnew/v1.1.4.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v1.1.4.rst b/doc/source/whatsnew/v1.1.4.rst index d0d03021629c6..b85a85a7e0595 100644 --- a/doc/source/whatsnew/v1.1.4.rst +++ b/doc/source/whatsnew/v1.1.4.rst @@ -15,6 +15,7 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ - Fixed regression where attempting to mutate a :class:`DateOffset` object would no longer raise an ``AttributeError`` (:issue:`36940`) +- Fixed regression where :meth:`DataFrame.agg` would fail with :exc:`TypeError` when passed positional arguments to be passed on to the aggregation function (:issue:`36948`). .. ---------------------------------------------------------------------------