diff --git a/pandas/core/apply.py b/pandas/core/apply.py index 0c2adb89a2422..585afc571132f 100644 --- a/pandas/core/apply.py +++ b/pandas/core/apply.py @@ -278,7 +278,7 @@ def transform_str_or_callable(self, func) -> DataFrame | Series: kwargs = self.kwargs if isinstance(func, str): - return self._try_aggregate_string_function(obj, func, *args, **kwargs) + return self._apply_str(obj, func, *args, **kwargs) if not args and not kwargs: f = com.get_cython_func(func) @@ -543,7 +543,7 @@ def apply_str(self) -> DataFrame | Series: self.kwargs["axis"] = self.axis else: self.kwargs["axis"] = self.axis - return self._try_aggregate_string_function(obj, f, *self.args, **self.kwargs) + return self._apply_str(obj, f, *self.args, **self.kwargs) def apply_multiple(self) -> DataFrame | Series: """ @@ -601,34 +601,32 @@ def normalize_dictlike_arg( func = new_func return func - def _try_aggregate_string_function(self, obj, arg: str, *args, **kwargs): + def _apply_str(self, obj, arg: str, *args, **kwargs): """ if arg is a string, then try to operate on it: - - try to find a function (or attribute) on ourselves + - try to find a function (or attribute) on obj - try to find a numpy function - raise """ assert isinstance(arg, str) - f = getattr(obj, arg, None) - if f is not None: + if hasattr(obj, arg): + f = getattr(obj, arg) if callable(f): return f(*args, **kwargs) - # people may try to aggregate on a non-callable attribute + # people may aggregate on a non-callable attribute # but don't let them think they can pass args to it assert len(args) == 0 assert len([kwarg for kwarg in kwargs if kwarg not in ["axis"]]) == 0 return f - - f = getattr(np, arg, None) - if f is not None and hasattr(obj, "__array__"): + elif hasattr(np, arg) and hasattr(obj, "__array__"): # in particular exclude Window + f = getattr(np, arg) return f(obj, *args, **kwargs) - - raise AttributeError( - f"'{arg}' is not a valid function for '{type(obj).__name__}' object" - ) + else: + msg = f"'{arg}' is not a valid function for '{type(obj).__name__}' object" + raise AttributeError(msg) class NDFrameApply(Apply):