因此,我试图实现的是在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')