I would like to create a method inside a class that gets a variable and a function as input arguments and return a new value. In below example the arbitrary function can be max, min, mean, or ...:
import pandas as pd
df = pd.DataFrame( {'col1': [1, 2], 'col2': [4, 6]})
df.max(axis=1), df.min(axis=1), df.mean(axis=1) # sample of methods that I would like to pass
I would like to do similar through a method inside a class. My attempt so far that does not work:
class our_class():
def __init__(self, df):
self.df = df
def arb_func(self, func):
return self.df.func()
ob1 = our_class(df)
ob1.arb_func(max(axis=1))
Any suggestions appreciated.
PS: It is a toy problem here. My goal is to be able to get a data frame and do arbitrary number of statistical analysis on it later. I do not want to hardcode the statistical analysis and let it change later if needed.
CodePudding user response:
You could try this:
class our_class():
def __init__(self, df):
self.df = df
def arb_func(self, func):
return func(self.df)
You could then use it like this:
ob1 = our_class(df)
ob1.arb_func(lambda x: x.max(axis=1))
CodePudding user response:
I assume the OP is trying to generate some generic coding interface for educational purposes?
Here a suggestion (which in my opinion is actually making the usage way more complex than necessary, as many other users have already noted in their questions/comments):
from functools import partial
import pandas as pd
df = pd.DataFrame({"a": [1, 2, 3]})
class our_class():
def __init__(self, df):
self.df = df
def arb_func(self, func: str, **kwargs):
return partial(getattr(pd.DataFrame, func), **kwargs)(df)
ob1 = our_class(df)
print(ob1.arb_func("max", axis=1))
0 1
1 2
2 3
dtype: int64
print(ob1.arb_func("max", axis=0))
a 3
dtype: int64
CodePudding user response:
You can pass the method name as a string (not a function object), create an expression with the help of f-string and evaluate it:
class our_class():
def __init__(self, df):
self.df = df
def arb_func(self, func):
return eval(f"self.df.{func}")
ob1 = our_class(df)
ob1.arb_func("max(axis=1)")
