有没有一种方法可以在特定对象上调度存储的函数



因此,我试图实现的是在dict对象中收集一些panda函数,其中是列名(字符串(,为函数列表(或任何其他集合(。然后,我希望能够从特定的df在相关列上调度这些函数。

我试着做一些类似的事情

dispatcher = {"ABC": pd.isnull}

但在尝试在df上运行此键值对的值后,我得到AttributeError:"Series"对象没有属性"x"。

这样的事情可以实现吗?

我也看到了这个线程,但它没有帮助,因为存储在其中的函数没有用于对象(数据帧(。

@编辑:我正在寻找一种可以让我存储这样的功能的东西:

dispatcher = {
"ABC": [func1, func2, func3],
"DEF": [func4, func5]
}

然后,在处理一些example_df时,将这些函数分派到相关列上。所以它会抛出如下函数:

example_df["ABC"].func1()
example_df["ABC"].func2()
example_df["ABC"].func3()
example_df["DEF"].func4()
example_df["DEF"].func5()

一个可能的解决方案(以玩具数据帧为例(:

text = """
a   b
NaN 2
1   3
"""
df = pd.read_csv(StringIO(text), sep='s+')
dispatcher = {"ABC": pd.isnull}
dispatcher.get('ABC')(df)

输出:

a      b
0   True  False
1  False  False

如果我们想指定应用pd.isnull的列:

from functools import partial
def dfnull(col, df):
return pd.isnull(df[col])
dispatcher = {"ABC": partial(dfnull, 'a')}
dispatcher.get('ABC')(df)

编辑1

以下代码应回答OP注释:

def createf(x):
return "partial(" + x[0].__name__ + ", '" + x[1] +"')"
cols = ['a', 'b']
funcs = [dfnull, dfnull]
d = dict(zip(cols, map(lambda x: eval(createf(x)), zip(funcs, cols))))
d.get('a')(df)
d.get('b')(df)

输出:

>>> d.get('a')(df)
0     True
1    False
Name: a, dtype: bool
>>> d.get('b')(df)
0    False
1    False
Name: b, dtype: bool

编辑2

以下内容应回答OP的第二条意见:

myfuncs = {'func1': pd.isnull, 'func2': pd.isna}
class MySeries(pd.Series):
def __init__(self, df):
super().__init__(df)

for key in myfuncs:
func = partial(myfuncs[key], df)
setattr(self, key, func)
MySeries(df['a']).func1()
MySeries(df['a']).func2()
MySeries(df['b']).func2()
MySeries(df['b']).func1()

输出:

>>> MySeries(df['a']).func1()
0     True
1    False
Name: a, dtype: bool
>>> MySeries(df['a']).func2()
0     True
1    False
Name: a, dtype: bool
>>> MySeries(df['b']).func2()
0    False
1    False
Name: b, dtype: bool
>>> MySeries(df['b']).func1()
0    False
1    False
Name: b, dtype: bool

要全部开火,只需使用以下命令:

mydict = {'a': {'func1': pd.isnull, 'func2': pd.isna},
'b': {'func1': pd.isnull, 'func2': pd.isna}}
def fire_all(col):
myfuncs = mydict[col]

class MySeries(pd.Series):
def __init__(self, df):
super().__init__(df)
for key in myfuncs:
func = partial(myfuncs[key], df)
setattr(self, key, func)

for f in myfuncs:
print(eval("MySeries(df[col])." + f + "()"))

fire_all('b')

最新更新