微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我有一个非常大的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之后可用的第一个函数,该函数将每个组中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提出的非常有效的解决方案是否适用于由多个列定义的组?在这种情况下,地图不起作用.也许合并?

解决方法:

在我的机器上,使用groupby然后映射它几乎快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 ms.

变换方法慢了近100倍:

%%timeit

df3 = df.copy()

df3[['B','C']] = df3.groupby('group').transform('first')

这将返回1个循环,最好是每个循环3:205 ms.

关于你关于使用多个群组的更新问题,@ jeff在以下评论中使用的建议

df['B'] = df.groupby(['group1','group2']).B.transform('first')
df['C'] = df.groupby(['group1','group2']).C.transform('first')

比一次转换两个列快大约50倍.这是因为目前变换对于Series来说效率要高得多,尽管有一个newly-created issue也可以提高DataFrames的操作速度.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐