首页 > 解决方案 > 通过子类别均值加速 Pandas fillna(如何替换 for 循环)

问题描述

我的数据包含在“RID”列中编码的几个子类别,我正在填充每个子类别的平均值。我一直在使用的代码非常慢。寻找一种更好的方法来摆脱 for 循环。

filled = mergedf.copy()
for c,v in enumerate(mergedf.RID.unique()):
    filled.loc[filled.RID == v, :] = filled.loc[filled.RID == v, :].fillna(filled.loc[filled.RID == v, :].mean())

filled.info()

我一直在尝试以下方法来加快速度,因为有人建议 groupby,但我无法让合并正常工作。

pts_mean = mergedf.groupby("RID").mean()
fill2 = merge.combine_first(pts_mean)

fill3 = pd.merge(mergedf, pts_mean, on="RID", how="left")

我已经尝试过 how = "inner" 以及 how = "outer"

查看我的测试数据,之前:

print(mergedf.loc[mergedf.RID==2,"FDG"])
0     1.36926
1     1.21655
2         NaN
3         NaN
4         NaN
5         NaN
6         NaN
7         NaN
8         NaN
9         NaN
10        NaN
11        NaN
12        NaN

在慢方法之后(这是想要的结果,我只是不希望它花这么长时间)

print(filled.loc[filled.RID==2,"FDG"])
0     1.369260
1     1.216550
2     1.292905
3     1.292905
4     1.292905
5     1.292905
6     1.292905
7     1.292905
8     1.292905
9     1.292905
10    1.292905
11    1.292905
12    1.292905

在 combine_first 方法之后

print(fill2.loc[fill2.RID==2,"FDG"])
0     1.369260
1     1.216550
2     1.292905
3     1.074235
4          NaN
5     1.319690
6          NaN
7          NaN
8     1.264300
9          NaN
10    1.042469
11         NaN
12         NaN

在 pd.merge 之后

print(fill3.loc[fill3.RID==2,["FDG_x","FDG_y"]])
      FDG_x     FDG_y
0   1.36926  1.292905
1   1.21655  1.292905
2       NaN  1.292905
3       NaN  1.292905
4       NaN  1.292905
5       NaN  1.292905
6       NaN  1.292905
7       NaN  1.292905
8       NaN  1.292905
9       NaN  1.292905
10      NaN  1.292905
11      NaN  1.292905
12      NaN  1.292905

标签: pandasdataframepandas-groupbyfillna

解决方案


让我们尝试以下操作,使用groupbywith transform

filled['FDG'].fillna(filled.groupby('RID')['FDG'].transform('mean'))

或者

fill4 = filled.fillna(filled.groupby('RID').transform('mean'))

推荐阅读