【问题标题】:Merge DataFrames in Pandas using the mean使用均值合并 Pandas 中的 DataFrame
【发布时间】:2013-10-29 16:22:14
【问题描述】:

我有一组带有数值和部分重叠索引的 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'])

这给了我两个 DataFrame:

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

现在我想合并 DataFrame 并取每个索引的平均值(如果适用,即如果它出现不止一次)。

应该是这样的:

    col
a     1
b     3
c     4
d     6

我可以通过一些高级合并/加入来做到这一点吗?

【问题讨论】:

    标签: python merge pandas


    【解决方案1】:

    类似这样的:

    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 非常简单。
    【解决方案2】:
    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's timeit module 运行等效的基准测试。它只需要更多的设置。 docs has some examples 展示了如何执行此操作。


    请注意,如果 df1df2 在其索引中有重复的条目,例如这样:

    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。两种解决方案中的哪一种会更快?
    • 好问题 ;) 我会尝试一些更大的数据。不过,第一个答案获胜。
    • @unutbu 感谢基准测试的答案,不过我肯定需要更多关于 Pandas 和数据分析的练习..
    • 一件小事:如果我在 DataFrames 中有更多列,我将如何定义我想要合并和平均 'col' 并对其他人执行另一个/不操作?
    • @MartinPreusse:您可以将上述任何一种方法应用于系列df1['col']df2['col']。例如,@Roman 的答案如下所示:pd.concat((df1['col'], df2['col']), axis=1).mean(axis=1)
    猜你喜欢
    • 2017-11-30
    • 2021-12-12
    • 1970-01-01
    • 2021-05-05
    • 2019-11-10
    • 2020-06-15
    • 2016-09-05
    • 2021-07-04
    • 2020-02-14
    相关资源
    最近更新 更多