python - 如何加快 Pandas 中每个 groupby 组的缺失值替换?

标签 python performance pandas dataframe nan

我有一个非常大的 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

在这里您可以看到,对于 group1group2 的每个唯一组合,列 BC 最多包含一个非缺失变量。

在每个 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,但似乎我需要应用它两次(ffillbfill)...有什么想法吗?

更新 下面 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/

相关文章:

ruby-on-rails - Rails 和 partials,是否有更有效的编写方法...?

python - 合并两个 TRUE/FALSE 数据框列仅保持 TRUE

python - 将 SAS 数据文件导入 python 数据框

python - Django + Angular2 : How to fetch data from database?

python - 从文本文件到字典

android - 为什么我的应用程序在第一次运行时启动速度非常慢(10 秒以上),在 android 5.0 上只显示白屏?

android - SlidingMenu 在显示 Activity 之前创建延迟

Python查找列表中元素的索引并在另一个列表中删除

python - 如何在多索引 Pandas 中按次日值填充缺失值?

pandas - 如何用 Pandas 索引值的唯一组合