Накопительная сумма с интервалами

Рассмотрим этот фрейм данных:

dfgg
Out[305]: 
                   Parts_needed   output
Year Month PartId              
2018 1     L27849            72    72
     2     L27849            75   147
     3     L27849           101   248
     4     L27849           103   351
     5     L27849            77
     6     L27849           120
     7     L27849            59
     8     L27849            79
     9     L27849            28
     10    L27849            64
     11    L27849           511
     12    L27849            34
2019 1     L27849            49
     2     L27849            68
     3     L27849            75
     4     L27849            45
     5     L27849            84
     6     L27849            42
     7     L27849            40
     8     L27849            52
     9     L27849           106
     10    L27849            75
     11    L27849           176
     12    L27849            58  2193
2020 1     L27849           135  2328
     2     L27849            45  2301
     3     L27849            21  2247
     4     L27849            35
     5     L27849            17
     6     L27849            39
                        ...
2025 7     L27849            94
     8     L27849            13
     9     L27849            94
     10    L27849            65
     11    L27849           141
     12    L27849            34
2026 1     L27849            22
     2     L27849           132
     3     L27849            49
     4     L27849            33
     5     L27849            48
     6     L27849            53
     7     L27849           103
     8     L27849           122
     9     L27849           171
     10    L27849           182
     11    L27849            68
     12    L27849            23
2027 1     L27849            44
     2     L27849            21
     3     L27849            52
     4     L27849            53
     5     L27849            57
     6     L27849           187
     7     L27849            69
     8     L27849            97
     9     L27849            31
     10    L27849            29
     11    L27849            33
     12    L27849            8

В этом фрейме данных мне нужно получить совокупную сумму Parts_needed с интервалом в 2 года. Например: for 1-2018, 72 будет продолжать добавляться в следующие строки от 75,101,103.. до 1-2020 135. Аналогично, в 2-2018, 75 будут добавляться следующие строки с 101,103.. по 2-2020 45. Однако за последние 2 года совокупная сумма будет по всем оставшимся строкам. Я не могу установить диапазон с помощью np.cumsum (). Кто-нибудь может мне помочь?

изменить: я отредактировал, чтобы включить ожидаемый результат. Для 2-2020 вывод будет 2328 + 45-72 (поскольку 72 добавлено на 2 года) Для 3-2020 вывод будет 2301 + 21-75 (поскольку 75 было добавлено на 2 года) и так далее.


person IndigoChild    schedule 23.03.2018    source источник
comment
Какой ожидаемый результат? Можете ли вы добавить это к вопросу, какие числа?   -  person jezrael    schedule 23.03.2018
comment
дайте мне минутку, я отредактирую и сообщу вам   -  person IndigoChild    schedule 23.03.2018
comment
Привет я отредактировал это   -  person IndigoChild    schedule 23.03.2018


Ответы (1)


Обычно вам нужна промежуточная сумма, если начало было дополнено нулями. Вы можете сделать это с помощью свертки. Вот простой пример numpy, который вы сможете адаптировать к своему варианту использования pandas:

import numpy as np
a = np.array([10,20,3,4,5,6,7])
width = 4
kernel = np.ones(width)
np.convolve(a,kernel)

возвращение

array([10., 30., 33., 37., 32., 18., 22., 18., 13.,  7.])

Как вы можете видеть, это совокупная сумма до 37 в выходных данных (или a[3]), а после этого - сумма скользящего окна из 4 элементов.

Это сработает для вас, если у вас всегда есть 24 строки за каждый двухлетний период.

Вот пример pandas, использующий только 2 месяца в году (поэтому width это 4 вместо 24):

>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame({'year':[18,18,19,19,20,20,21,21],'month':[1,2,1,2,1,2,1,2],'parts':[230,5,2,12,66,32,1,2]})
>>> df
   month  parts  year
0      1    230    18
1      2      5    18
2      1      2    19
3      2     12    19
4      1     66    20
5      2     32    20
6      1      1    21
7      2      2    21
>>> width = 4
>>> kernel = np.ones(width)
>>> # Drop the last elements as you don't want the window to roll passed the end
>>> np.convolve(df['parts'],kernel)[:-width+1]
array([230., 235., 237., 249.,  85., 112., 111., 101.])

Теперь вы просто назначаете этот последний массив новому столбцу вашего DataFrame

person Dan    schedule 23.03.2018