使用均值合并Pandas中的数据框。

21

我有一组具有数值的DataFrame,并且它们的索引存在部分重叠。我想将它们合并,并在一个索引在多个DataFrame中出现时取平均值。

import pandas as pd
import numpy as np

df1 = pd.DataFrame([1,2,3], columns=['col'], index=['a','b','c'])
df2 = pd.DataFrame([4,5,6], columns=['col'], index=['b','c','d'])

这使得我获得了两个数据帧(DataFrames):

   col            col
a    1        b     4
b    2        c     5
c    3        d     6

现在我想合并这些数据框,并对每个索引进行平均值计算(如果适用,即如果它出现多次)。

应该看起来像这样:

    col
a     1
b     3
c     4
d     6

我能用一些高级的合并/连接方法来做到这一点吗?

2个回答

20

像这样的东西:

df3 = pd.concat((df1, df2))
df3.groupby(df3.index).mean()

#    col
# a    1
# b    3
# c    4
# d    6

或者反过来,就像@unutbu的答案一样:

pd.concat((df1, df2), axis=1).mean(axis=1)

谢谢,速度很快。Pandas 真是太简单了。 - Martin Preusse

5
In [22]: pd.merge(df1, df2, left_index=True, right_index=True, how='outer').mean(axis=1)
Out[23]: 
a    1
b    3
c    4
d    6
dtype: float64

关于Roman的问题,我发现IPython%timeit命令是一个方便的基准测试代码的方法:

In [28]: %timeit df3 = pd.concat((df1, df2)); df3.groupby(df3.index).mean()
1000 loops, best of 3: 617 µs per loop

In [29]: %timeit pd.merge(df1, df2, left_index=True, right_index=True, how='outer').mean(axis=1)
1000 loops, best of 3: 577 µs per loop

In [39]: %timeit pd.concat((df1, df2), axis=1).mean(axis=1)
1000 loops, best of 3: 524 µs per loop

在这种情况下,pd.concat(...).mean(...) 显得更快一些。但是我们应该测试更大的数据框以获得更有意义的基准测试结果。
顺便说一下,如果您不想安装IPython,可以使用 Python的timeit模块 运行等效的基准测试。只需要进行一些更多的设置。文档中有一些示例展示了如何做到这一点。
请注意,如果 df1 df2 在其索引中具有重复的条目,例如像这样:
N = 1000
df1 = pd.DataFrame([1,2,3]*N, columns=['col'], index=['a','b','c']*N)
df2 = pd.DataFrame([4,5,6]*N, columns=['col'], index=['b','c','d']*N)

然后这三个答案给出了不同的结果:

In [56]: df3 = pd.concat((df1, df2)); df3.groupby(df3.index).mean()
Out[56]: 
   col
a    1
b    3
c    4
d    6

pd.merge 可能不能给出您想要的答案:

In [58]: len(pd.merge(df1, df2, left_index=True, right_index=True, how='outer').mean(axis=1))
Out[58]: 2002000

pd.concat((df1, df2), axis=1) 报错 ValueError:

In [48]: pd.concat((df1, df2), axis=1)
ValueError: cannot reindex from a duplicate axis

+1 我还在学习Pandas。哪个解决方案会更快? - Roman Pekar
好问题 ;) 我会在一些更大的数据上尝试两种方法。不过第一个答案获胜。 - Martin Preusse
@unutbu,谢谢你对答案进行基准测试,虽然我确实需要更多的练习来提高在Pandas和数据分析方面的能力。 - Roman Pekar
一个小问题:如果我的数据框中有更多的列,我该如何定义我想要合并和平均“col”,并对其他列执行另一种/无操作? - Martin Preusse
@MartinPreusse:你可以将上述任何一种方法应用于Series df1['col']df2['col']。例如,@Roman的答案看起来像这样:pd.concat((df1['col'], df2['col']), axis=1).mean(axis=1) - unutbu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接