我有一个大型的数据框(约80万行)。例如,将近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
现在我在第3行和第4行中有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
不在其中。 / p>
将行中的NaN
值迅速替换为相似行中的值。例如,对于row3
,我们首先检查similar_for_row3
中的所有行,然后使用数据帧中存在的第一行(即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循环”迭代所有Dataframe来替换NaN值,但这非常慢。更换一行需要我大约3秒钟的时间。我的数据集有80万行。我要花一个月的时间去做。请帮忙!
答案 0 :(得分:1)
- 如何快速检查相似帧_行_3和相似行_行4中的这些行是否在数据框中,例如,'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行,就像您提到的“ Dataframe中存在的第一行”一样。
- 用相似行中的NaN值快速替换行中的NaN值。例如,对于第3行,我们首先检查相似_行_3中的所有行,然后使用数据帧中存在的第一行(即test.loc [test ['name'== 3]])替换第3行中的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
上进行简单循环,找到每次迭代中要替换的最相似的行。