Вы можете использовать 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')
.