您可以使用rgettattr 从系列中获取属性testframe[col]:
例如,
In [74]: s = pd.Series(['1','2'])
In [75]: rgetattr(s, 'str.replace')('1', 'A')
Out[75]:
0 A
1 2
dtype: object
import functools
import pandas as pd
def rgetattr(obj, attr, *args):
def _getattr(obj, attr):
return getattr(obj, attr, *args)
return functools.reduce(_getattr, [obj] + attr.split('.'))
testframe = pd.DataFrame.from_dict({'col1': [1, 2], 'col2': [3, 4]})
funcdict = {'col1': ['astype', 'str.replace'],
'col2': ['astype', 'str.replace']}
argdict = {'col1': [['str'], ['1', 'A']], 'col2': [['str'], ['3', 'B']]}
for col in testframe.columns:
for attr, args in zip(funcdict[col], argdict[col]):
testframe[col] = rgetattr(testframe[col], attr)(*args)
print(testframe)
产量
col1 col2
0 A B
1 2 4
getattr 是 Python 标准库中的函数,用于在以字符串形式给出名称时从对象获取命名属性。例如,给定
In [92]: s = pd.Series(['1','2']); s
Out[92]:
0 1
1 2
dtype: object
我们可以得到s.str使用
In [85]: getattr(s, 'str')
Out[85]: <pandas.core.strings.StringMethods at 0x7f334a847208>
In [91]: s.str == getattr(s, 'str')
Out[91]: True
要获得s.str.replace,我们需要
In [88]: getattr(getattr(s, 'str'), 'replace')
Out[88]: <bound method StringMethods.replace of <pandas.core.strings.StringMethods object at 0x7f334a847208>>
In [90]: s.str.replace == getattr(getattr(s, 'str'), 'replace')
Out[90]: True
但是,如果我们指定
funcdict = {'col1': ['astype', 'str.replace'],
'col2': ['astype', 'str.replace']}
那么我们需要某种方式来处理需要一次调用getattr(例如getattr(testframe[col], 'astype'))的情况,而不是需要多次调用getattr(例如getattr(getattr(testframe[col], 'str'), 'replace'))的情况。
为了将这两种情况统一为一种简单的语法,我们可以使用rgetattr,这是getattr 的递归替换,它可以处理字符串属性名称的点链,例如'str.replace'。
递归由reduce 处理。
文档以reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 计算((((1+2)+3)+4)+5) 为例。同样,您可以想象+ 被getattr 替换,以便rgetattr(s, 'str.replace') 计算getattr(getattr(s, 'str'), 'replace')。