Скользящее среднее значение панд, основанное на группировании по нескольким столбцам - PullRequest
1 голос
/ 11 июня 2019

У меня есть длинный формат данных с повторяющимися значениями в двух столбцах и данными в другом столбце.Я хочу найти SMA для каждой группы.Моя проблема: rolling() просто игнорирует тот факт, что данные сгруппированы по двум столбцам.

Вот некоторые фиктивные данные и код.

import numpy as np
import pandas as pd

dtix=pd.Series(pd.date_range(start='1/1/2019', periods=4) )
df=pd.DataFrame({'ix1':np.repeat([0,1],4), 'ix2':pd.concat([dtix,dtix]), 'data':np.arange(0,8) })
df

ix1 ix2 data
0   0   2019-01-01  0
1   0   2019-01-02  1
2   0   2019-01-03  2
3   0   2019-01-04  3
0   1   2019-01-01  4
1   1   2019-01-02  5
2   1   2019-01-03  6
3   1   2019-01-04  7

Теперь, когда я выполняю групповое скользящее среднее для этих данных, я получаю вывод, подобный этому:

df.groupby(['ix1','ix2']).agg({'data':'mean'}).rolling(2).mean()
        data
ix1 ix2 
0   2019-01-01  NaN
    2019-01-02  0.5
    2019-01-03  1.5
    2019-01-04  2.5
1   2019-01-01  3.5
    2019-01-02  4.5
    2019-01-03  5.5
    2019-01-04  6.5

Желаемый результат: Принимая во внимание то, что я действительно хотел бы получить, это:


sma
ix1 ix2 
0   2019-01-01  NaN
    2019-01-02  0.5
    2019-01-03  1.5
    2019-01-04  2.5
1   2019-01-01  NaN
    2019-01-02  4.5
    2019-01-03  5.5
    2019-01-04  6.5

Буду признателен за вашу помощь в этом.

1 Ответ

0 голосов
/ 11 июня 2019

Используйте еще один groupby по первому уровню (ix1) с rolling:

df1 = (df.groupby(['ix1','ix2'])
         .agg({'data':'mean'})
         .groupby(level=0, group_keys=False)
         .rolling(2)
         .mean())
print (df1)
                data
ix1 ix2             
0   2019-01-01   NaN
    2019-01-02   0.5
    2019-01-03   1.5
    2019-01-04   2.5
1   2019-01-01   NaN
    2019-01-02   4.5
    2019-01-03   5.5
    2019-01-04   6.5

В вашем решении после агрегации агрегации возвращается один столбец DataFrame, с такой цепочкой rolling, работающий со всеми строками, а не с группами, как нужно:

print(df.groupby(['ix1','ix2']).agg({'data':'mean'}))
                data
ix1 ix2             
0   2019-01-01     0
    2019-01-02     1
    2019-01-03     2
    2019-01-04     3
1   2019-01-01     4
    2019-01-02     5
    2019-01-03     6
    2019-01-04     7
...