我有一个非常大的 pandas 数据集,其中的数据看起来像
df = pd.DataFrame({'group1' : ['A', 'A', 'A', 'A',
'B', 'B', 'B', 'B'],
'group2' : ['C', 'C', 'C', 'D',
'E', 'E', 'F', 'F'],
'B' : ['one', np.NaN, np.NaN, np.NaN,
np.NaN, 'two', np.NaN, np.NaN],
'C' : [np.NaN, 1, np.NaN, np.NaN,
np.NaN, np.NaN, np.NaN, 4]})
df
Out[64]:
B C group1 group2
0 one NaN A C
1 NaN 1 A C
2 NaN NaN A C
3 NaN NaN A D
4 NaN NaN B E
5 two NaN B E
6 NaN NaN B F
7 NaN 4 B F
在这里您可以看到,对于 group1
和 group2
的每个唯一组合,列 B
和 C
最多包含一个非缺失变量。
在每个 groupby(['group1','group2'])
组中,我通过使用唯一的非缺失值(在那个组)如果该值存在。
为此,我使用 groupby
之后可用的 first
函数,它将每个组中 B 或 C 的第一个非缺失值传播到其余组该组中的缺失值:
df[['B','C']]=df.groupby(['group1','group2']).transform('first')
df
Out[62]:
B C group1 group2
0 one 1 A C
1 one 1 A C
2 one 1 A C
3 NaN NaN A D
4 two NaN B E
5 two NaN B E
6 NaN 4 B F
7 NaN 4 B F
不幸的是,这在我非常大的数据集上非常慢。你在这里看到任何提高速度的方法吗?我在考虑 fillna
,但似乎我需要应用它两次(ffill
和 bfill
)...有什么想法吗?
更新 下面 ajcr
提出的非常有效的解决方案是否适用于由多个列定义的组? map
在这种情况下不起作用。也许合并
?
最佳答案
在我的机器上,使用 groupby
然后使用 map
可以快将近 100 倍:
g = df.groupby('group', sort=False).first()
df['B'] = df['group'].map(g['B'])
df['C'] = df['group'].map(g['C'])
这是一个包含 1000 个组和 10000 行的测试 DataFrame:
df = pd.DataFrame({'group': np.repeat(np.arange(1000), 10),
'B': np.nan,
'C': np.nan})
df.ix[4::10, 'B':'C'] = 5 # every 4th row of a group is non-null
时间安排:
%%timeit
df2 = df.copy()
g = df2.groupby('group', sort=False).first()
df2['B'] = df2['group'].map(g['B'])
df2['C'] = df2['group'].map(g['C'])
这将返回 100 个循环,最好是 3 个循环:每个循环 2.29 毫秒
。
transform
方法慢了将近 100 倍:
%%timeit
df3 = df.copy()
df3[['B','C']] = df3.groupby('group').transform('first')
这将返回 1 个循环,最好是 3 个循环:每个循环 205 毫秒
。
关于您更新了有关使用多个组的问题,@jeff 在下面的评论中提出了使用建议
df['B'] = df.groupby(['group1','group2']).B.transform('first')
df['C'] = df.groupby(['group1','group2']).C.transform('first')
比一次转换两列快大约 50 倍。这是因为目前 transform
对 Series 的性能要好得多,尽管有一个 newly-created issue。也可以提高对 DataFrame 的操作速度。
关于python - 如何加快 Pandas 中每个 groupby 组的缺失值替换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36286803/