问题
Consider this dataframe:
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
In this dataframe, I need to obtain cumulative sum of Parts_needed at intervals of 2 years. For eg:
for 1-2018, 72
will keep getting added to the following rows 75,101,103..
upto 1-2020 135
. Similarly, at 2-2018, 75
will keep getting added to the following rows 101,103..
upto 2-2020 45
. For the last 2 years however, the cumulative sum will be for whatever rows are remaining. I'm not being able to set a range with np.cumsum() Can somebody help me please?
edit: I have edited, to include the expected output. For 2-2020, the output is 2328+45-72 (since 72 has been added for 2 years) For 3-2020, the output is 2301+21-75 (since 75 has been added for 2 years) and so on.
回答1:
Basically you want a running total if the beginning was zero padded. You can do that with convolution. Here is a simple numpy example which you should be able to adapt to your pandas use case:
import numpy as np
a = np.array([10,20,3,4,5,6,7])
width = 4
kernel = np.ones(width)
np.convolve(a,kernel)
returning
array([10., 30., 33., 37., 32., 18., 22., 18., 13., 7.])
As you can see this is a cumulative sum up until 37
in the output (or a[3]
) and after that it's a sum of a rolling 4 element window.
This will work for you assuming you always have 24 rows for each 2 year period.
Here is a pandas example using only 2 months per year (so width
is 4
instead of 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.])
Now you just assign that last array to a new column of your DataFrame
来源:https://stackoverflow.com/questions/49445729/cumulative-sum-at-intervals