Как переписать в цикл агрегации объектов?

    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 после создания функции можно в цикле вызывать функцию с различными аргументами.

→ Ссылка