[英]Replace NaN values in a Pandas DataFrame column after using centered .rolling() with first computed sum
我是Pandas的新手,这也是我的第一个实际问题Stackoverflow,请耐心等待。
我正在使用MultiIndex转换DataFrame。 我必须计算五个观察值的移动总和,并将其居中。 我在使用groupby时已经做到了这一点,这样就可以在每个组中计算出滚动总和,即性别,年龄和分组类型。 但是,这意味着每组中的前两行均为NaN。 我希望前两个NaN值等于第三个,而后两个等于第3个。
这是原始的DataFrame
Gender Type Age Value
1 'f' A 1 654
2 'f' A 2 665
3 'f' A 3 684
4 'f' A 4 688
5 'f' A 5 651
6 'f' A 6 650
7 'f' A 7 698
8 'f' A 8 689
9 'f' A 9 648
10 'f' A 10 654
11 'f' B 1 623
12 'f' B 2 620
13 'f' B 3 623
14 'f' B 4 653
15 'f' B 5 653
16 'f' B 6 642
17 'f' B 7 632
18 'f' B 8 632
19 'f' B 9 644
20 'f' B 10 654
21 'm' A 1 623
22 'm' A 2 624
23 'm' A 3 600
24 'm' A 4 642
25 'm' A 5 622
26 'm' A 6 623
27 'm' A 7 633
28 'm' A 8 635
29 'm' A 9 653
30 'm' A 10 623
31 'm' B 1 623
32 'm' B 2 632
33 'm' B 3 632
34 'm' B 4 683
35 'm' B 5 652
36 'm' B 6 655
37 'm' B 7 691
38 'm' B 8 684
39 'm' B 9 645
40 'm' B 10 624
这是我用于计算滚动总和的代码。
df=df.reset_index().set_index(['Age'])
df=df.groupby(['Gender','Type'])['Value'].rolling(window=5,center=True).sum().reset_index()
计算如下:
Gender Type Age Value
1 'f' A 1 NaN
2 'f' A 2 NaN
3 'f' A 3 3342
4 'f' A 4 3338
5 'f' A 5 3371
6 'f' A 6 3376
7 'f' A 7 3336
8 'f' A 8 3339
9 'f' A 9 NaN
10 'f' A 10 NaN
11 'f' B 1 NaN
12 'f' B 2 NaN
13 'f' B 3 3172
14 'f' B 4 3191
15 'f' B 5 3203
16 'f' B 6 3212
17 'f' B 7 3203
18 'f' B 8 3204
19 'f' B 9 NaN
20 'f' B 10 NaN
21 'm' A 1 NaN
22 'm' A 2 NaN
23 'm' A 3 x1
24 'm' A 4 x2
25 'm' A 5 x3
26 'm' A 6 x4
27 'm' A 7 x5
28 'm' A 8 x7
29 'm' A 9 NaN
30 'm' A 10 NaN
31 'm' B 1 NaN
32 'm' B 2 NaN
33 'm' B 3 x8
34 'm' B 4 x9
35 'm' B 5 x10
36 'm' B 6 x11
37 'm' B 7 x12
38 'm' B 8 x13
39 'm' B 9 NaN
40 'm' B 10 NaN
x只是滚动总和的替代。
现在我的问题。 我想将NaN值替换为每组中的特定单元格。 具体来说,每组1年和2年的滚动总和必须等于3年。 由于3年行由于不可计算而也可能是NaN,因此我无法使用仅向前和向后推断填充或填充的代码。 如果3年是NaN,我也希望小组中的1年和2年。
因此,以下结果是我想要的:
Gender Type Age Value
1 'f' A 1 3342
2 'f' A 2 3342
3 'f' A 3 3342
4 'f' A 4 3338
5 'f' A 5 3371
6 'f' A 6 3376
7 'f' A 7 3336
8 'f' A 8 3339
9 'f' A 9 3339
10 'f' A 10 3339
11 'f' B 1 3172
12 'f' B 2 3172
13 'f' B 3 3172
14 'f' B 4 3191
15 'f' B 5 3203
16 'f' B 6 3212
17 'f' B 7 3203
18 'f' B 8 3204
19 'f' B 9 3204
20 'f' B 10 3204
21 'm' A 1 x1
22 'm' A 2 x1
23 'm' A 3 x1
24 'm' A 4 x2
25 'm' A 5 x3
26 'm' A 6 x4
27 'm' A 7 x5
28 'm' A 8 x7
29 'm' A 9 x7
30 'm' A 10 x7
31 'm' B 1 x8
32 'm' B 2 x8
33 'm' B 3 x8
34 'm' B 4 x9
35 'm' B 5 x10
36 'm' B 6 x11
37 'm' B 7 x12
38 'm' B 8 x13
39 'm' B 9 x13
40 'm' B 10 x13
我真的希望你们中的一个能帮助我。 提前致谢。
在使用rolling.sum
初始groupby
rolling.sum
,尝试使用customer def
groupby.transform
:
第一组进行NaN
3年级测试
df.loc[2, 'Value'] = np.nan
print(df)
Gender Type Age Value
0 'f' A 1 NaN
1 'f' A 2 NaN
2 'f' A 3 NaN
3 'f' A 4 3338.0
4 'f' A 5 3371.0
5 'f' A 6 3376.0
6 'f' A 7 3336.0
7 'f' A 8 3339.0
8 'f' A 9 NaN
9 'f' A 10 NaN
10 'f' B 1 NaN
...
def custom_rolling_fillna(arr):
arr.iloc[:2] = arr.iloc[2]
arr.iloc[-2:] = arr.iloc[-3]
return arr
df['Value'] = df.groupby(['Gender', 'Type'])['Value'].transform(custom_rolling_fillna)
print(df)
Gender Type Age Value
0 'f' A 1 NaN
1 'f' A 2 NaN
2 'f' A 3 NaN
3 'f' A 4 3338.0
4 'f' A 5 3371.0
5 'f' A 6 3376.0
6 'f' A 7 3336.0
7 'f' A 8 3339.0
8 'f' A 9 3339.0
9 'f' A 10 3339.0
10 'f' B 1 3172.0
...
或者,您可以使用以下步骤一步一步完成:
def custom_rolling_fillna(arr):
rolling = arr.rolling(window=5,center=True).sum()
rolling.iloc[:2] = arr.iloc[2]
rolling.iloc[-2:] = arr.iloc[-3]
return rolling
df['Value'] = df.groupby(['Gender', 'Type'])['Value'].transform(custom_rolling_fillna)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.