I can call an arbitrary method defined via a string variable on a pandas series. The way I would do it would be like this:
import pandas as pd
method_name = 'mean'
pd.Series([1, 2, 3]).__getattr__(method_name)()
Now I want to do the same with a rolling pandas series, the way I would do it would be like this:
import pandas as pd
method_name = 'mean'
pd.Series([1, 2, 3]).rolling(window=1).__getattr__(method_name)()
I get the following error when doing it:
AttributeError: 'Rolling' object has no attribute 'mean'
Is there a way to call an arbitrary method (mean, median, max, min, quantile) on a rolling pandas series?
Thanks!
CodePudding user response:
You can read about getattr and getattribute from the Python documentation (Data Model): getattr and getattribute
The use of getattribute will solve your problem;
import pandas as pd
method_name = 'mean'
pd.Series([1, 2, 3]).rolling(window=1).__getattribute__(method_name)()
Output
0 1.0
1 2.0
2 3.0
dtype: float64
CodePudding user response:
The method __getattr__
must be implemented for each object. This is unlike __getatrribute__
which is a method in the base object
class in Python. When calling __getatrr__
, you will get that object implementation of this method (if any). For rolling
, the definition is below, which basically does some checking for caching/pickling purposes (the _internal_names_set
), if not found, it checks the dataframe (the self.obj
):
def __getattr__(self, attr: str):
if attr in self._internal_names_set:
return object.__getattribute__(self, attr)
if attr in self.obj:
return self[attr]
raise AttributeError(
f"'{type(self).__name__}' object has no attribute '{attr}'"
)
To avoid this, use the getattr
builtin function:
>> getattr(df.rolling(3), 'mean')
I like getattr
because it allows you to specify a third, optional argument for when the attribute is not defined:
>> getattr(df.rolling(3), 'mean', None)