【问题标题】:Python/Numpy - calculate sum of equal array elementsPython/Numpy - 计算相等数组元素的总和
【发布时间】:2015-03-26 20:23:05
【问题描述】:

我有两个 numpy 数组,看起来像:

field = np.array([5,1,3,3,2,1,6])    
counts = np.array([100,210,300,150,20,90,170])

它们没有排序(也不应该改变)。我现在想计算第三个数组(具有相同的长度和顺序),只要它们位于同一字段中,它就包含计数的总和。这里的结果应该是:

field_counts = np.array([100,300,450,450,20,300,170])

数组非常长,因此遍历它(并且总是查看相应的合作伙伴字段在哪里)效率太低了。也许我只是没有看到树木的树木......我希望有人可以帮助我!

【问题讨论】:

  • 旁白:当您发现自己需要groupby 操作时,这通常表明您应该使用pandas 而不是numpy;您的操作类似于df.groupby("field")["counts"].transform(sum)

标签: python arrays numpy sum unique


【解决方案1】:

我不知道它是否足够高效(因为我确实迭代了field)但这里有一个建议。我首先创建一个字段/计数值目录。然后,我根据它创建一个数组。

from collections import defaultdict
dic = defaultdict(int)
for j, f in enumerate(field):
    dic[f] += counts[j]

field_counts = np.array([dic[f] for f in field])

【讨论】:

    【解决方案2】:

    使用以下列表理解:

    >>> [np.sum(counts[np.where(field==i)]) for i in field]
    [100, 300, 450, 450, 20, 300, 170]
    

    您可以通过np.where 获取field 中相同元素的索引:

    >>> [np.where(field==i) for i in field]
    [(array([0]),), (array([1, 5]),), (array([2, 3]),), (array([2, 3]),), (array([4]),), (array([1, 5]),), (array([6]),)]
    

    然后通过索引获取counts的对应元素!并用np.sum 计算sum

    【讨论】:

    • 如果数组很长,这会很慢;您已经进行了 N^2 计算。
    【解决方案3】:

    这个问题可以使用numpy_indexed 包以完全矢量化的方式解决(免责声明:我是它的作者)

    import numpy_indexed as npi
    g = npi.group_by(field)
    field_counts = g.sum(counts)[1][g.inverse]
    

    g.sum 计算每组唯一字段的总和,然后 g.inverse 将这些值映射回原始字段。

    【讨论】:

    • 费尽心思打包这个功能是有原因的,因为确实有很多这类问题。在我看来,所有这些问题都将从我的回答中受益;和这个一样。它在几个方面大大改进了当前接受的答案。据我了解,您所指的部分是针对商业目的的;但这是一个像啤酒一样免费的开源包,但如果我错了,请纠正我。我唯一自私的动机是让它得到更好的测试:)。
    • 主观上,如果我提到我的作者身份,我感觉更像是在自我推销;但谢谢你的提醒。您是否碰巧有任何资源的链接,这些资源对商业和非商业目的之间的区别更加明确?
    • 其中一些是重复的,我会说,是的。我会按照你的建议公开作者身份,谢谢。
    • 非常感谢您的反馈
    • 真棒@EelcoHoogendoorn 我看到你添加了披露:)。请对您的其他答案也这样做。作为旁注,如果其中一些是重复的,请随意标记它们!我将删除我以前的 cmets 进行清理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 2016-07-21
    • 2019-05-17
    相关资源
    最近更新 更多