python - 使用居中 .rolling() 后,用第一个计算总和替换 Pandas DataFrame 列中的 NaN 值

标签 python pandas dataframe pandas-groupby

我对 Pandas 还很陌生,这也是我在 Stackoverflow 上遇到的第一个实际问题,所以请耐心等待。

我正在使用 MultiIndex 转换 DataFrame。我必须计算每个观察值的移动总和,并将其居中。我在使用 groupby 时做到了这一点,这样在每个组内计算滚动总和,即按性别、年龄和类型分组。然而,这意味着每组中的第一行和最后两行都是 NaN。我希望前两个 NaN 值等于第三个,最后两个等于第三个。

这是原始的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,因此我无法使用仅向前和向后推断 bfill 或 hfill 的代码。如果 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 后,尝试 groupby.transform与客户 def:

设置

为第一组设置第 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)

关于python - 使用居中 .rolling() 后,用第一个计算总和替换 Pandas DataFrame 列中的 NaN 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55651890/

相关文章:

python - 当 'ID' 为 1 时,如何创建一个新列插入分组列 'interaction'(及时)的单元格值

pandas - 如何将包含元组列表的字典内的字典转换为 pandas 数据框

pandas - Jupyter Notebook 仍然截断 pandas 列

python - Pandas:检查另一列中是否存在子字符串,然后创建一个具有特定值的新列

python - 在数据框中保留连续的天数

javascript - Flask、python字典转highcharts JS图

python - 如何对 pandas 数据框中的列表进行分组

python - 错误 : object of type 'zip' has no len() after adding extra header by using zip

Python - 使用排序操作列和行 - reshape

python - 如何在没有类型的情况下打印 defaultdict 变量?