Как переписать в цикл агрегации объектов?
stats2 = stats.groupby([ha])[s].rolling(7,min_period=7).std(ddof=0).to_frame().reset_index()
stats2[s] = stats2.groupby([ha])[s].shift(+1).fillna(0.01)
stats2 = stats2.sort_values('level_1').reset_index()
stats['std{}_{}'.format(d,s)] = stats2[s]
stats2 = stats.groupby([ha])[s].rolling(7,min_period=7).mean().to_frame().reset_index()
stats2[s] = stats2.groupby([ha])[s].shift(+1).fillna(0.01)
stats2 = stats2.sort_values('level_1').reset_index()
stats['mean{}_{}'.format(d,s)] = stats2[s]
stats2 = stats.groupby([ha])[s].rolling(7,min_period=7).median().to_frame().reset_index()
stats2[s] = stats2.groupby([ha])[s].shift(+1).fillna(0.01)
stats2 = stats2.sort_values('level_1').reset_index()
stats['median{}_{}'.format(d,s)] = stats2[s]
Как это переписать в цикл?
Данный пример для: std, mean, median.
Ответы (2 шт):
Автор решения: CrazyElf
→ Ссылка
Ну как-то так, наверное:
for method in ['std', 'mean', 'median']:
stats2 = stats.groupby([ha])[s].rolling(7,min_period=7)
if method == 'std':
stats2 = stats2.std(ddof=0)
elif method == 'mean':
stats2 = stats2.mean()
elif method == 'median':
stats2 = stats2.mean()
else:
# тут как-то обработать ошибку "неизвестный метод"
pass
stats2 = stats2.to_frame().reset_index()
stats2[s] = stats2.groupby([ha])[s].shift(+1).fillna(0.01)
stats2 = stats2.sort_values('level_1').reset_index()
stats[method + '{}_{}'.format(d,s)] = stats2[s]
Как сами методы через список передать не соображу. Но вообще можно через partial попробовать, если очень нужно.
Набросал вариант через partial, попробуйте:
from pandas.core.window import Rolling
from functools import partial
for method,func in [('std',partial(Rolling.std, ddof=0)), ('mean',Rolling.mean), ('median',Rolling.median)]:
stats2 = stats.groupby([ha])[s].rolling(7,min_period=7)
stats2 = func(stats2)
stats2 = stats2.to_frame().reset_index()
stats2[s] = stats2.groupby([ha])[s].shift(+1).fillna(0.01)
stats2 = stats2.sort_values('level_1').reset_index()
stats[method + '{}_{}'.format(d,s)] = stats2[s]
Автор решения: MaxU
→ Ссылка
Почему бы не воспользоваться стандартным методом .agg('<method_name>'):
def fun(df, method="mean", **kwargs)
stats2 = df.groupby([ha])[s].rolling(7,min_period=7).agg(method, **kwargs).to_frame().reset_index()
stats2[s] = stats2.groupby([ha])[s].shift(+1).fillna(0.01)
stats2 = stats2.sort_values('level_1').reset_index()
stats['std{}_{}'.format(d,s)] = stats2[s]
Отказ от ответственности: функция может содержать ошибки, т.к. в вопросе отсутствует воспроизводимый пример данных, который позволил бы протестировать работу функции.
Прототип, построенный на игрушечном примере данных:
DataFrame:
In [18]: df = pd.DataFrame(np.random.randint(5, size=(10, 3)), columns=list("abc"))
In [19]: df
Out[19]:
a b c
0 2 4 4
1 4 0 1
2 2 1 2
3 3 2 1
4 1 4 3
5 1 1 3
6 4 1 0
7 1 3 3
8 4 0 2
9 2 0 2
Проверка идеи:
In [20]: df.groupby("a")["b"].rolling(3, min_period=1).std(ddof=0)
Out[20]:
a
1 4 NaN
5 NaN
7 1.247219
2 0 NaN
2 NaN
9 1.699673
3 3 NaN
4 1 NaN
6 NaN
8 0.471405
Name: b, dtype: float64
In [21]: df.groupby("a")["b"].rolling(3, min_period=1).agg("std", ddof=0)
Out[21]:
a
1 4 NaN
5 NaN
7 1.247219
2 0 NaN
2 NaN
9 1.699673
3 3 NaN
4 1 NaN
6 NaN
8 0.471405
Name: b, dtype: float64
PS после создания функции можно в цикле вызывать функцию с различными аргументами.