pandas - 通过子类别均值加速 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
解决方案
让我们尝试以下操作,使用groupby
with transform
:
filled['FDG'].fillna(filled.groupby('RID')['FDG'].transform('mean'))
或者
fill4 = filled.fillna(filled.groupby('RID').transform('mean'))
推荐阅读
- java - 如何使用 Spring MVC 更新当前用户数据?
- ruby-on-rails - 仅在注册页面上包含 javascript 文件 - Rails & Turbolinks
- android - 使用 Kotlin 中的 Acitvty 列表创建 Recyclerview
- email - Mule Imap 连接器返回空的正文内容
- c# - Anotar.Serilog [LogToErrorOnException] 添加捕获
- html - 如何从父元素强制!important?
- excel - 将数组元素写入 shell 脚本中的 excel 工作表
- python - 无法通过 pip 安装 python3 包
- xamarin - Xamarin Forms Map Viewable Area 事件处理程序
- bash - 从 bash 获取 tcsh 脚本