IIUC, начиная с вашего кода
import pandas as pd
import numpy as np
import datetime
vals = [-4,17,-4,-16,2,20,3,10,-17,-8,-21,2,0,-11,16,-24,-10,-21,5,12,14,9,-15,-15]
grp = ['X']*6 + ['Y'] * 6 + ['X']*6 + ['Y'] * 6
typ = ['foo']*12+['bar']*12
dat = ['19/01/18','19/01/18','22/01/18','22/01/18','23/01/18','24/01/18'] * 4
df = pd.DataFrame({'group': grp,'type':typ,'value':vals,'date':dat})
df.date = pd.to_datetime(df.date)
Мы начинаем с группировки по group
с, type
с и date
с и просто суммируем в течение каждого дня:
df2 = df.groupby(["group", "type", "date"]).sum().reset_index().sort_values("date")
Теперь вы можете просто выполнить rolling
sum () с помощью min_periods=1
, чтобы ваше первое значение не было NaN
.Тем не менее, вы не будете
k = df2.groupby(["group", "type"]).value.rolling(window=2, min_periods=1).sum()
Это даст
group type
X bar 0 -11.0
1 -19.0
2 -18.0
3 -31.0
foo 4 13.0
5 -7.0
6 -18.0
7 22.0
Y bar 8 17.0
9 40.0
10 8.0
11 -30.0
foo 12 13.0
13 -12.0
14 -46.0
15 -19.0
, что уже то, что вы хотите, но без ваших date
значений.Чтобы получить даты, мы можем сделать здесь трюк, который состоит в том, чтобы просто изменить третий уровень вашего мультииндексного объекта для ваших значений date
в аналогичном df, сгруппированных таким же образом.Следовательно, мы можем сделать
aux = df2.groupby(["group", "type", "date"]).date.rolling(2).count().index.get_level_values(2)
и заменить индекс:
k.index = pd.MultiIndex.from_tuples([(k.index[x][0], k.index[x][1], aux[x]) for x in range(len(k.index))])
Наконец, у вас есть ожидаемый результат:
k.to_frame()
group type date value
0 X bar 2018-01-19 -11.0
1 X bar 2018-01-22 -19.0
2 X bar 2018-01-23 -18.0
3 X bar 2018-01-24 -31.0
4 X foo 2018-01-19 13.0
5 X foo 2018-01-22 -7.0
6 X foo 2018-01-23 -18.0
7 X foo 2018-01-24 22.0
8 Y bar 2018-01-19 17.0
9 Y bar 2018-01-22 40.0
10 Y bar 2018-01-23 8.0
11 Y bar 2018-01-24 -30.0
12 Y foo 2018-01-19 13.0
13 Y foo 2018-01-22 -12.0
14 Y foo 2018-01-23 -46.0
15 Y foo 2018-01-24 -19.0