diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 0de9bebd68045..b83208ef497d3 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -634,6 +634,7 @@ Numeric a ``TypeError`` was wrongly raised. For all three methods such calculation are now done correctly. (:issue:`16679`). - Bug in :class:`Series` comparison against datetime-like scalars and arrays (:issue:`22074`) - Bug in :class:`DataFrame` multiplication between boolean dtype and integer returning ``object`` dtype instead of integer dtype (:issue:`22047`,:issue:`22163`) +- Bug in :meth:`DataFrame.apply` where, when supplied with a string argument and additional positional or keyword arguments (e.g. ``df.apply('sum', min_count=1)``), a ``TypeError`` was wrongly raised (:issue:`22376`) - Strings diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 989becbf133ca..40cd952a62138 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -71,7 +71,9 @@ def __init__(self, obj, func, broadcast, raw, reduce, result_type, self.result_type = result_type # curry if needed - if kwds or args and not isinstance(func, np.ufunc): + if ((kwds or args) and + not isinstance(func, (np.ufunc, compat.string_types))): + def f(x): return func(x, *args, **kwds) else: diff --git a/pandas/tests/frame/test_apply.py b/pandas/tests/frame/test_apply.py index f18163d51c721..8beab3fb816df 100644 --- a/pandas/tests/frame/test_apply.py +++ b/pandas/tests/frame/test_apply.py @@ -120,14 +120,17 @@ def test_apply_standard_nonunique(self): rs = df.T.apply(lambda s: s[0], axis=0) assert_series_equal(rs, xp) - @pytest.mark.parametrize('arg', ['sum', 'mean', 'min', 'max', 'std']) - def test_with_string_args(self, arg): - result = self.frame.apply(arg) - expected = getattr(self.frame, arg)() - tm.assert_series_equal(result, expected) - - result = self.frame.apply(arg, axis=1) - expected = getattr(self.frame, arg)(axis=1) + @pytest.mark.parametrize('func', ['sum', 'mean', 'min', 'max', 'std']) + @pytest.mark.parametrize('args,kwds', [ + pytest.param([], {}, id='no_args_or_kwds'), + pytest.param([1], {}, id='axis_from_args'), + pytest.param([], {'axis': 1}, id='axis_from_kwds'), + pytest.param([], {'numeric_only': True}, id='optional_kwds'), + pytest.param([1, None], {'numeric_only': True}, id='args_and_kwds') + ]) + def test_apply_with_string_funcs(self, func, args, kwds): + result = self.frame.apply(func, *args, **kwds) + expected = getattr(self.frame, func)(*args, **kwds) tm.assert_series_equal(result, expected) def test_apply_broadcast_deprecated(self):