Скользящая сумма панд для умножения значений отдельно

У меня есть следующий фрейм данных:

a = pd.DataFrame({'unit': [2, 2, 3, 3, 3, 4, 4, 4, 5], 
                 'date': [1, 2, 1, 2, 3, 1, 2, 3, 1], 
                 'revenue': [1, 1, 3, 5, 7, 6, 6, 2, 9]})

Pandas Rolling.sum с окном = 2:

a['rolled_sum'] = a.rolling(2, on='date').sum().shift(+1)['revenue']

вычисляет эту сумму строка за строкой:

 adunit   date  revenue  rolled_sum
0   2       1       1       NaN
1   2       2       1       NaN
2   3       1       3       2.0
3   3       2       5       4.0
4   3       3       7       8.0
5   4       1       6       12.0
6   4       2       6       13.0
7   4       3       2       12.0
8   5       1       9       8.0

Я хотел бы, чтобы эта скользящая сумма рассчитывалась для каждой единицы отдельно:

 adunit   date  revenue  rolled_sum
0   2       1       1       NaN
1   2       2       1       NaN
2   3       1       3       NaN
3   3       2       5       NaN
4   3       3       7       8.0
5   4       1       6       NaN
6   4       2       6       NaN
7   4       3       2       12.0
8   5       1       9       NaN

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

Любые идеи?

Спасибо заранее :)

Энди


person Andrzej Wodecki    schedule 22.10.2019    source источник


Ответы (2)


IIUC, вы можете кататься по группам:

a['rolled_sum'] = (a.groupby('unit')
                    .rolling(2, on='date').sum()['revenue']
                    .groupby('unit').shift(1)
                    .to_numpy()
                  )

Выход:

   unit  date  revenue  rolled_sum
0     2     1        1         NaN
1     2     2        1         NaN
2     3     1        3         NaN
3     3     2        5         NaN
4     3     3        7         8.0
5     4     1        6         NaN
6     4     2        6         NaN
7     4     3        2        12.0
8     5     1        9         NaN
person Quang Hoang    schedule 22.10.2019

С помощью сортировки вы можете замаскировать, где ее не следует устанавливать.

m = a.unit.eq(a.unit.shift()) & a.unit.eq(a.unit.shift(-1))
a['rolled_sum'] = (a.rolling(2, on='date').sum().shift(+1)['revenue']
                     .where(m.shift().fillna(False)))

   unit  date  revenue  rolled_sum
0     2     1        1         NaN
1     2     2        1         NaN
2     3     1        3         NaN
3     3     2        5         NaN
4     3     3        7         8.0
5     4     1        6         NaN
6     4     2        6         NaN
7     4     3        2        12.0
8     5     1        9         NaN
person ALollz    schedule 22.10.2019