如何用熊猫的2列groupby平均值中位数填充NA?

时间:2019-12-22 18:10:28

标签: python pandas pandas-groupby nan fillna

使用熊猫,我有一个具有两个层次结构AB的数据框,其中B可以是NaN,我想在其中的D中填充一些NaN一种特殊的方式:

在下面的示例中,A具有“ B子组”,其中D根本没有值(例如(1, 1)),而A在其他子组中也具有D的值(例如(1, 3) )。

现在,我想获取每个子组的mean(对于120, 90 and 75A==1,找到这些均值的median(对于{{ 1}}),并使用此中位数填充90其他子组中的NaN。

A==1这样的组中,只有D的NaN不能填充。

A==1这样的组,其中有D的一些值,但只有B为NaN的行在D中具有NaN,如果可能的话,不应该填充它们(我打算稍后用的所有值的平均值来填充它们整个A组中的D个。

示例df:

A==2
A==3

预期结果:

d = {'A': [1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3], 
    'B': [1, 2, 3, 3, 4, 5, 6, 1, 1, np.NaN, np.NaN], 
    'D': [np.NaN, np.NaN, 120, 120, 90, 75, np.NaN, np.NaN, 60, 50, np.NaN]}
df = pd.DataFrame(data=d)

使用A B D 1 1 NaN 1 2 NaN 1 3 120 1 3 120 1 4 90 1 5 75 1 6 NaN 2 1 NaN 3 1 60 3 NaN 50 3 NaN NaN A B D 1 1 90 1 2 90 1 3 120 1 3 120 1 4 90 1 5 75 1 6 90 2 1 NaN 3 1 60 3 NaN 50 3 NaN NaN 似乎可以得到正确的值,但是使用

df.groupby(['A', 'B'])['D'].mean().groupby(['A']).agg('median')

似乎没有更改D中的任何值。

非常感谢您的帮助,我已经坚持了一段时间,在任何地方都找不到任何解决方案。

1 个答案:

答案 0 :(得分:3)

您的第一步是正确的。之后,我们使用Series.map将正确的中位数映射到列A中的每个组。

最后,如果D,我们使用np.where有条件地填充列B is not NaN

medians = df.groupby(['A', 'B'])['D'].mean().groupby(['A']).agg('median')
df['D'] = np.where(df['B'].notna(),                        # if B is not NaN
                   df['D'].fillna(df['A'].map(medians)),   # fill in the median
                   df['D'])                                # else keep the value of column D
    A    B      D
0   1 1.00  90.00
1   1 2.00  90.00
2   1 3.00 120.00
3   1 3.00 120.00
4   1 4.00  90.00
5   1 5.00  75.00
6   1 6.00  90.00
7   2 1.00    nan
8   3 1.00  60.00
9   3  nan  50.00
10  3  nan    nan
相关问题