python - 如何用相似行列表中的值快速填充一行中的 NaN 值
问题描述
我有一个大数据框(大约 800,000 行)。近 30% 的行具有 NaN 值,例如,
test = pd.DataFrame({"name": [1,2,3,4,5,6,7],
"col1": ['c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7'],
"col2": [4, 5, 6, np.nan, np.nan, 8, 5],
"col3": [7, 8, 9, np.nan, np.nan, 3, 7],
"col4": [7, 8, 9, np.nan, np.nan, 2, 6]})
name col1 col2 col3 col4
0 1 c1 4.0 7.0 7.0
1 2 c2 5.0 8.0 8.0
2 3 c3 6.0 9.0 9.0
3 4 c4 NaN NaN NaN
4 5 c5 NaN NaN NaN
5 6 c6 8.0 3.0 2.0
6 7 c7 5.0 7.0 6.0
现在我在 row3 和 row4 中有 NaN。
根据一些规则,我得到 row3 最相似的行是
similar_for_row3 = ['name' = 10, 'name' = 3, 'name' = 1]
并且对于第 4 行是
similar_for_row4 = ['name' = 2, 'name' = 6, 'name' = 20].
然后,我的问题是:
如何快速检查这些行
similar_for_row3
是否similar_for_row4
在数据框中,例如,'name' = 10
不在'name' = 20
其中。NaN
用相似行中的值快速替换一行中的值。例如,对于row3
,我们首先检查 中的所有行similar_for_row3
,然后使用 Dataframe 中存在的第一行(即test.loc[test['name' == 3]]
)来替换NaN
inrow3
。
输出是:
name col1 col2 col3 col4
0 1 c1 4.0 7.0 7.0
1 2 c2 5.0 8.0 8.0
2 3 c3 6.0 9.0 9.0
3 4 c4 6.0 9.0 9.0 -> replace NaN with 'name' = 3
4 5 c5 NaN NaN NaN
5 6 c6 8.0 3.0 2.0
6 7 c7 5.0 7.0 6.0
我试图用“for循环”迭代所有Dataframe来替换NaN值,但它很慢。更换一排大约需要 3 秒。我的数据集有 800,000 行。我要花一个月的时间来做这件事。请帮忙!
解决方案
- 如何快速检查similar_for_row3 和similar_for_row4 中的这些行是否在数据框中,例如,'name' = 10 和'name' = 20 不在其中。
sets
您可以使用&
, 并使用sorted
设置找到两者的交集,key= similar_for_row3.index
以便使用出现的第一个交集similar_for_row3
:
similar_for_row4 = [2, 6, 20]
fill_with = sorted(list(set(similar_for_row4) & set(test.name.values)),
key= similar_for_row4.index)[0]
#2
所以这里第 2 行将用于替换第 4 行,正如您提到的“数据框中存在的第一行”。
- 用相似行中的值快速替换一行中的 NaN 值。例如,对于row3,我们首先检查similar_for_row3中的所有行,然后使用Dataframe中存在的第一行(即test.loc[test['name' == 3]])替换row3中的NaN。
.isnull()
您可以首先使用在特定行上切片的数据帧上创建一个掩码,然后对数据帧执行布尔索引以过滤相应的列,在这种情况下为第 2 行:
row = 4
mask = test.loc[row, :].isnull().squeeze()
test.loc[row, mask] = test.loc[fill_with, mask].values
因此,对于此示例,您将拥有:
name col1 col2 col3 col4
0 1 c1 4.0 7.0 7.0
1 2 c2 5.0 8.0 8.0
2 3 c3 6.0 9.0 9.0
3 4 c4 NaN NaN NaN
4 5 c5 6.0 9.0 9.0
5 6 c6 8.0 3.0 2.0
6 7 c7 5.0 7.0 6.0
更新
为了轻松检测存在任何 NaN 的行,您可以执行以下操作:
has_nans = test[test.isnull().any(axis=1)].index.values
并且简单地循环has_nans
查找在每次迭代中要替换的最相似的行。
推荐阅读
- node.js - pm2 守护进程在几个小时后死亡
- jgrapht - JGraphT 中的“GetDiameter”函数会占用大量内存吗?
- linux - 如何仅在 bash 脚本中获取文件作为输出
- c# - 从对象列表中选择对象,从 DropDownList
- apache-spark - org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.token.SecretManager$InvalidToken):令牌已过期
- python - 不退出 For 循环
- c# - 以编程方式创建 SSIS 2019 包时出错
- python - 无头 Chrome 下载低分辨率图像
- html - blockquote 不返回任何内容
- java - 如何将日期字符串从 JSON 转换为时间跨度