Python 计算累积的远期金额
假设我们有以下数据帧:Python 计算累积的远期金额,python,pandas,numpy,dataframe,Python,Pandas,Numpy,Dataframe,假设我们有以下数据帧: Date Type Country Value 0 2016-04-30 A NL 1 1 2016-04-30 A BE 2 2 2016-04-30 B NL 3 3 2016-04-30 B BE 4 4 2016-04-30 C NL 5 5 2016-04-30 C BE 6 6 2016-04-30 C
Date Type Country Value
0 2016-04-30 A NL 1
1 2016-04-30 A BE 2
2 2016-04-30 B NL 3
3 2016-04-30 B BE 4
4 2016-04-30 C NL 5
5 2016-04-30 C BE 6
6 2016-04-30 C FR 7
7 2016-04-30 C UK 8
8 2016-05-31 A NL 9
9 2016-05-31 A BE 10
10 2016-05-31 A FR 11
11 2016-05-31 B NL 12
12 2016-05-31 B BE 13
13 2016-05-31 B FR 14
14 2016-05-31 C NL 15
15 2016-05-31 C BE 16
16 2016-05-31 C UK 17
17 2016-05-31 C SL 18
18 2016-06-30 A NL 19
19 2016-06-30 B FR 20
20 2016-06-30 B UK 21
21 2016-06-30 B SL 22
22 2016-06-30 C NL 23
23 2016-06-30 C BE 24
24 2016-07-31 A NL 25
25 2016-07-31 A BE 23
26 2016-07-31 B FR 12
27 2016-07-31 B UK 28
28 2016-07-31 B SL 22
29 2016-07-31 C NL 25
30 2016-07-31 C BE 28
对应于以下代码:
df = pd.DataFrame([['2016-04-30','A','NL',1], ['2016-04-30','A', "BE" ,2], ['2016-04-30', 'B', 'NL',3], ['2016-04-30','B','BE',4], ['2016-04-30','C','NL',5], ['2016-04-30','C','BE',6],['2016-04-30','C','FR', 7], ['2016-04-30','C','UK',8], ['2016-05-31','A','NL',9], ['2016-05-31','A','BE',10], ['2016-05-31','A','FR',11], ['2016-05-31','B','NL',12], ['2016-05-31','B','BE',13], ['2016-05-31','B','FR',14], ['2016-05-31','C','NL',15], ['2016-05-31','C','BE',16], ['2016-05-31','C','UK',17], ['2016-05-31','C','SL',18], ['2016-06-30','A','NL',19], ['2016-06-30','B','FR',20], ['2016-06-30','B','UK',21], ['2016-06-30','B','SL',22], ['2016-06-30','C','NL',23], ['2016-06-30','C','BE',24], ['2016-07-31', 'A', 'NL', 25], ['2016-07-31', 'A', 'BE', 23], ['2016-07-31', 'B', 'FR',12], ['2016-07-31','B','UK', 28], ['2016-07-31','B', 'SL',22], ['2016-07-31', 'C', 'NL', 25], ['2016-07-31', 'C', 'BE', 28] ], columns=['Date','Type' ,'Country' ,'Value'])
我想创建一个额外的列“CumValue”,它计算接下来K个月的累计总和(在本例中,假设K=3,但我希望它是通用的)。例如,对于观察[2016-04-30,A,NL],我希望CumValue为1+9+19=28(因此我们包括最初的月份)。例如,假设两个月前的观测不可用,那么我们将该值设置为NaN
我希望最终产品如下所示:
Date Type Country Value CumValue
0 2016-04-30 A NL 1 29
1 2016-04-30 A BE 2 NaN
2 2016-04-30 B NL 3 NaN
3 2016-04-30 B BE 4 NaN
4 2016-04-30 C NL 5 43
5 2016-04-30 C BE 6 46
6 2016-04-30 C FR 7 NaN
7 2016-04-30 C UK 8 NaN
8 2016-05-31 A NL 9 53
9 2016-05-31 A BE 10 NaN
10 2016-05-31 A FR 11 NaN
11 2016-05-31 B NL 12 NaN
12 2016-05-31 B BE 13 NaN
13 2016-05-31 B FR 14 46
14 2016-05-31 C NL 15 63
15 2016-05-31 C BE 16 68
16 2016-05-31 C UK 17 NaN
17 2016-05-31 C SL 18 NaN
18 2016-06-30 A NL 19 NaN
19 2016-06-30 B FR 20 NaN
20 2016-06-30 B UK 21 NaN
21 2016-06-30 B SL 22 NaN
22 2016-06-30 C NL 23 NaN
23 2016-06-30 C BE 24 NaN
24 2016-07-31 A NL 25 NaN
25 2016-07-31 A BE 23 NaN
26 2016-07-31 B FR 12 NaN
27 2016-07-31 B UK 28 NaN
28 2016-07-31 B SL 22 NaN
29 2016-07-31 C NL 25 NaN
30 2016-07-31 C BE 28 NaN
pd.merge(df, df.set_index('Date').groupby(['Type', 'Country']).Value.apply(lambda x: x.asfreq('1M').rolling(3).sum().shift(-2)).reset_index(), on=['Type', 'Country', 'Date']).rename(columns={'Value_x': 'Value', 'Value_y': 'CumValue'})
有人知道这样做的有效方法吗?您可以尝试下面的代码。我检查了(NL,A),(NL,C),(NL,BE)的输出,它似乎工作了
def shift_cum(x,k=3):
return x.rolling(k).sum().shift(-2)
df.assign(CumValue=df.groupby(['Country','Type'])['Value'].apply(shift_cum))
在这里,我们在默认值为3的函数中传递值,k
,您可以在应用时更改该值。该函数首先获取组内的滚动总和,然后将其向后移动2个位置以满足您的要求。仅当所有月份值连续可用时才起作用。OP声明:
例如,假设两个月前的观察结果不正确
如果可用,则将该值设置为NaN
这是类型
'A'、国家
'BE'的情况:没有2016-06-30的数据可用,因此结果应为NaN。
为了使其也适用于这种情况,您可以按如下方式修改解决方案:
Date Type Country Value CumValue
0 2016-04-30 A NL 1 29
1 2016-04-30 A BE 2 NaN
2 2016-04-30 B NL 3 NaN
3 2016-04-30 B BE 4 NaN
4 2016-04-30 C NL 5 43
5 2016-04-30 C BE 6 46
6 2016-04-30 C FR 7 NaN
7 2016-04-30 C UK 8 NaN
8 2016-05-31 A NL 9 53
9 2016-05-31 A BE 10 NaN
10 2016-05-31 A FR 11 NaN
11 2016-05-31 B NL 12 NaN
12 2016-05-31 B BE 13 NaN
13 2016-05-31 B FR 14 46
14 2016-05-31 C NL 15 63
15 2016-05-31 C BE 16 68
16 2016-05-31 C UK 17 NaN
17 2016-05-31 C SL 18 NaN
18 2016-06-30 A NL 19 NaN
19 2016-06-30 B FR 20 NaN
20 2016-06-30 B UK 21 NaN
21 2016-06-30 B SL 22 NaN
22 2016-06-30 C NL 23 NaN
23 2016-06-30 C BE 24 NaN
24 2016-07-31 A NL 25 NaN
25 2016-07-31 A BE 23 NaN
26 2016-07-31 B FR 12 NaN
27 2016-07-31 B UK 28 NaN
28 2016-07-31 B SL 22 NaN
29 2016-07-31 C NL 25 NaN
30 2016-07-31 C BE 28 NaN
pd.merge(df, df.set_index('Date').groupby(['Type', 'Country']).Value.apply(lambda x: x.asfreq('1M').rolling(3).sum().shift(-2)).reset_index(), on=['Type', 'Country', 'Date']).rename(columns={'Value_x': 'Value', 'Value_y': 'CumValue'})
这将产生OP中给出的第二行的正确结果:
Date Type Country Value CumValue
0 2016-04-30 A NL 1 29.0
1 2016-04-30 A BE 2 NaN
...
(此处接受的答案给出的值为35)