猿问

如何使用类似行列表中的值快速填充一行中的 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]

而对于 row4 是


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中的row3。


输出是:


    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 循环”迭代所有数据帧来替换 NaN 值,但速度很慢。更换一行大约需要 3 秒钟。我的数据集有 800,000 行。这将花费我一个月的时间来完成。请帮忙!


森林海
浏览 243回答 1
1回答

吃鸡游戏

如何快速检查similar_for_row3 和similar_for_row4 中的这些行是否在Dataframe 中,例如'name' = 10 和'name' = 20 不在其中。您可以sets使用&和 usesorted设置找到两者的交集,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 = 4mask = test.loc[row, :].isnull().squeeze()test.loc[row, mask] = test.loc[fill_with, mask].values因此,对于此示例,您将拥有:    name col1 col2  col3  col40     1   c1   4.0   7.0   7.01     2   c2   5.0   8.0   8.02     3   c3   6.0   9.0   9.03     4   c4   NaN   NaN   NaN4     5   c5   6.0   9.0   9.05     6   c6   8.0   3.0   2.06     7   c7   5.0   7.0   6.0更新为了轻松检测存在任何 NaN 的行,您可以执行以下操作:has_nans = test[test.isnull().any(axis=1)].index.values并且简单地循环has_nans查找在每次迭代中替换的最相似的行。
随时随地看视频慕课网APP

相关分类

Python
我要回答