Я пытаюсь создать функцию, которая выполняет повторную выборку данных временных рядов в pandas
. Я хотел бы иметь возможность указать тип агрегации, который происходит в зависимости от того, какой тип данных я отправляю (т.е. для некоторых данных подходит сумма каждого бина, а для других требуется среднее значение, так далее.). Например такие данные:
import pandas as pd
import numpy as np
dr = pd.date_range('01-01-2020', '01-03-2020', freq='1H')
df = pd.DataFrame(np.random.rand(len(dr)), index=dr)
У меня могла бы быть такая функция:
def process(df, freq='3H', method='sum'):
r = df.resample(freq)
if method == 'sum':
r = r.sum()
elif method == 'mean':
r = r.mean()
#...
#more options
#...
return r
Для небольшого количества методов агрегации это нормально, но кажется утомительным, если я хочу выбрать из все возможные варианты.
Я надеялся использовать getattr
для реализации что-то вроде этого post (в разделе Приведение в действие: обобщение вызовов методов). Однако я не могу найти способ сделать это:
def process2(df, freq='3H', method='sum'):
r = df.resample(freq)
foo = getattr(r, method)
return r.foo()
#fails with:
#AttributeError: 'DatetimeIndexResampler' object has no attribute 'foo'
def process3(df, freq='3H', method='sum'):
r = df.resample(freq)
foo = getattr(r, method)
return foo(r)
#fails with:
#TypeError: __init__() missing 1 required positional argument: 'obj'
Я понимаю, почему process2
терпит неудачу (вызов r.foo()
ищет метод foo()
из r
, а не переменную foo
). Но я не думаю, что понимаю, почему process3
терпит неудачу.
Я знаю, что другим подходом будет передача функций параметру method
, а затем apply
этих функций r
. Я склоняюсь к тому, что это будет менее эффективно? И это по-прежнему не позволяет мне напрямую обращаться к встроенным методам Resample.
Есть ли рабочий, более краткий способ добиться этого? Спасибо!
.resample().apply(method)
- person RichieV   schedule 13.08.2020method
быть строкой или это должна быть ссылка на фактический метод. - person RichieV   schedule 13.08.2020apply
. Насколько я могу судить,r.apply('sum')
совпадает сr.sum()
. По времени тестирования они кажутся эквивалентными - person Tom   schedule 13.08.2020