【问题标题】:computing sum of pandas dataframes计算熊猫数据帧的总和
【发布时间】:2015-01-02 16:04:50
【问题描述】:

我有两个要按 bin 方式添加的数据框。也就是说,给定

dfc1 = pd.DataFrame(list(zip(range(10),np.zeros(10))), columns=['bin', 'count'])
dfc2 = pd.DataFrame(list(zip(range(0,10,2), np.ones(5))), columns=['bin', 'count'])

这给了我这个

dfc1:

       bin  count
0        0      0
1        1      0
2        2      0
3        3      0
4        4      0
5        5      0
6        6      0
7        7      0
8        8      0
9        9      0

dfc2:

       bin  count
0        0      1
1        2      1
2        4      1
3        6      1
4        8      1

我想生成这个:

       bin  count
0        0      1
1        1      0
2        2      1
3        3      0
4        4      1
5        5      0
6        6      1
7        7      0
8        8      1
9        9      0

我在其中添加了 bin 列匹配的计数列。

事实上,我只加了 1(也就是说,dfc2 中的计数始终为 1)。所以这个问题的另一个版本是“给定一个 bin 值数组 (dfc2.bin),我如何在 dfc1 中为每个对应的计数值添加一个?”

到目前为止,我唯一的解决方案感觉非常低效(并且最终有点不可读),在两个 bin 列之间进行外部连接,从而创建了第三个数据框,我在该数据框上进行计算,然后投影出不需要的列。

建议?

【问题讨论】:

    标签: python python-3.x pandas


    【解决方案1】:

    首先将bin设置为两个数据帧的索引,然后您可以使用add,如果数据帧中缺少bin,则需要填充值来指示应使用零:

    dfc1 = dfc1.set_index('bin')
    dfc2 = dfc2.set_index('bin')
    result = pd.DataFrame.add(dfc1, dfc2, fill_value=0)
    

    Pandas 自动对具有相同索引的行求和。

    顺便说一句,如果你需要经常执行这样的操作,我强烈推荐使用numpy.bincount,它甚至可以在一个数据帧内重复bin索引

    【讨论】:

    • 就像我的回答一样,addcombineAdd 在这种情况下会非常有效,+1
    • 感谢有关 numpy.bincount 的说明,很好的建议。实际上,我可以稍微修改我的代码,以便我只有一组 numpy 数组(例如,dfc2 的数组([0,2,4,6,8]))。我将不得不计时,看看构建数组数组、展平和调用 bincount 是否比通过数据帧更好或更差。
    • 附录:使用 numpy.bincount 的代码非常简单(并且足够高效),以至于它在没有完成时间比较的情况下获胜。
    【解决方案2】:

    由于 dfc1 索引与您的“bin”值相同,您可以简单地执行以下操作:

    dfc1.iloc[dfc2.bin].cnt += 1
    

    请注意,我将您的“count”列重命名为“cnt”,因为 count 是 pandas 内置的,这可能会导致混淆和错误!

    【讨论】:

    • 虽然它完全实现了 OP 所追求的,但是这种解决方案效率并不高。
    • 它有什么低效的地方?
    • 您的方法是尝试修改现有数据框,这就像在 for 循环下操作列表...您明白了。并尝试运行 %timeit,我敢打赌它比其他方法慢得多,OP 显然想要效率。
    • 不要误会我的意思,我认为您的方法是最明智的答案,因为您的方法不需要在 bin 上建立索引,但是 OP 并没有询问 如何如何改进
    【解决方案3】:

    作为@Alleo 答案的替代方案,您可以使用方法combineAdd 简单地将2 个数据帧和set_index 同时添加在一起,前提是它们的索引将由bin 匹配:

    dfc1.set_index('bin').combineAdd(dfc2.set_index('bin')).reset_index()
    
       bin  count
    0    0      1
    1    1      0
    2    2      1
    3    3      0
    4    4      1
    5    5      0
    6    6      1
    7    7      0
    8    8      1
    9    9      0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-11
      • 1970-01-01
      • 1970-01-01
      • 2021-08-18
      • 1970-01-01
      • 2020-01-26
      • 2013-12-20
      • 1970-01-01
      相关资源
      最近更新 更多