diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 8fb74e2e87174..ac173c5182bc7 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -111,8 +111,14 @@ def get_result(self): # string dispatch if isinstance(self.f, compat.string_types): - self.kwds['axis'] = self.axis - return getattr(self.obj, self.f)(*self.args, **self.kwds) + # Support for `frame.transform('method')` + # Some methods (shift, etc.) require the axis argument, others + # don't, so inspect and insert if nescessary. + func = getattr(self.obj, self.f) + sig = compat.signature(func) + if 'axis' in sig.args: + self.kwds['axis'] = self.axis + return func(*self.args, **self.kwds) # ufunc elif isinstance(self.f, np.ufunc): diff --git a/pandas/tests/frame/test_apply.py b/pandas/tests/frame/test_apply.py index a057ca0879cac..af39c8f01cf73 100644 --- a/pandas/tests/frame/test_apply.py +++ b/pandas/tests/frame/test_apply.py @@ -4,6 +4,7 @@ import pytest +import operator from datetime import datetime import warnings @@ -880,6 +881,16 @@ def f(): with np.errstate(all='ignore'): df.agg({'A': ['abs', 'sum'], 'B': ['mean', 'max']}) + @pytest.mark.parametrize('method', [ + 'abs', 'shift', 'pct_change', 'cumsum', 'rank', + ]) + def test_transform_method_name(self, method): + # https://github.com/pandas-dev/pandas/issues/19760 + df = pd.DataFrame({"A": [-1, 2]}) + result = df.transform(method) + expected = operator.methodcaller(method)(df) + tm.assert_frame_equal(result, expected) + def test_demo(self): # demonstration tests df = pd.DataFrame({'A': range(5), 'B': 5})