pandas-dev/pandas · error · AttributeError
'{}' is not a valid function for '{type(obj).__name__}' obje
Error message
'{}' is not a valid function for '{type(obj).__name__}' object What it means
Raised in `_apply_str` when the string `func` is neither an attribute of the target object nor a numpy function available on its `__array__`. pandas tries `getattr(obj, func)` first, then `getattr(np, func)`; if both fail, it raises AttributeError indicating the name is invalid for this object type.
Source
Thrown at pandas/core/apply.py:846
assert isinstance(func, str)
if hasattr(obj, func):
f = getattr(obj, func)
if callable(f):
return f(*args, **kwargs)
# 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 not any(kwarg == "axis" for kwarg in kwargs)
return f
elif hasattr(np, func) and hasattr(obj, "__array__"):
# in particular exclude Window
f = getattr(np, func)
return f(obj, *args, **kwargs)
else:
msg = f"'{func}' is not a valid function for '{type(obj).__name__}' object"
raise AttributeError(msg)
class NDFrameApply(Apply):
"""
Methods shared by FrameApply and SeriesApply but
not GroupByApply or ResamplerWindowApply
"""
obj: DataFrame | Series
@property
def index(self) -> Index:
return self.obj.index
@property
def agg_axis(self) -> Index:
return self.obj._get_agg_axis(self.axis)
View on GitHub (pinned to 71959b8cb9)
Solutions
- Check that the method exists on the object: `hasattr(df, func)` or `hasattr(np, func)`.
- Pass the callable directly instead of a string: `df.apply(np.sqrt)` rather than `df.apply('sqrt')`.
- For element-wise numpy functions, use `df.applymap(np.sqrt)` (or `df.map` on newer versions).
Example fix
# before
df.apply('sqrt')
# after
df.apply(np.sqrt)
# or for element-wise
df.map(np.sqrt) Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
def resolve_func_name(obj, name):
if hasattr(obj, name) and callable(getattr(obj, name)):
return name
if hasattr(np, name) and hasattr(obj, '__array__'):
return name
raise AttributeError(f'{name!r} not valid for {type(obj).__name__}')
# usagedf.apply(resolve_func_name(df, candidate)) Type guard
def is_valid_func_name(obj, name) -> bool:
import numpy as np
return (hasattr(obj, name) and callable(getattr(obj, name))) or (hasattr(np, name) and hasattr(obj, '__array__')) Try / catch
try:
df.apply(name)
except AttributeError as e:
if 'is not a valid function' in str(e):
df.apply(getattr(np, name)) # fall back to numpy callable
else:
raise Prevention
- Prefer passing callables directly over string method names where possible.
- Check `hasattr(df, name)` before dispatching dynamically.
When it happens
Trigger: `df.apply('nonexistent_method')`, `series.apply('mean_x')` (typo), or `df.apply('sqrt')` when 'sqrt' is not a DataFrame method (it is a numpy/Series ufunc but not a DataFrame method). Different object types expose different method sets.
Common situations: Typo in a method name; assuming a method exists on DataFrame when it only exists on Series (or vice versa); version upgrades that renamed/removed a method; passing a numpy function name that the object type does not expose.
Related errors
- Operation {func} does not support axis=1
- the 'numba' engine doesn't support using a string as the cal
- invalid value for result_type, must be one of {None, 'reduce
- cannot perform both aggregation and transformation operation
- The 'numba' engine doesn't support list-like/dict likes of c
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/647e6bbe6c3ddd2e.
Report an issue: GitHub.