我刚接触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
我真的希望你们中的一个能帮助我。预先感谢。
答案 0 :(得分:0)
在初始groupby
和rolling.sum
之后,尝试与客户def
进行groupby.transform
:
第3组NaN
用于第一组考试
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)