【问题标题】:NumPy sum one array based on values in another array for each matching element in 3rd arrayNumPy 根据另一个数组中的值对第三个数组中的每个匹配元素求和一个数组
【发布时间】:2017-12-29 06:09:36
【问题描述】:

我有两个 numpy 数组,一个包含值,一个包含每个值类别。

values=np.array([1,2,3,4,5,6,7,8,9,10])
valcats=np.array([101,301,201,201,102,302,302,202,102,301])

我有另一个数组,其中包含我想要汇总的唯一类别。

categories=np.array([101,102,201,202,301,302])

我的问题是,我将运行相同的求和过程数十亿次,每一微秒都很重要。

我目前的实现如下。

catsums=[]
for x in categories:
    catsums.append(np.sum(values[np.where(valcats==x)]))

生成的 catsums 应该是:

[1, 14, 7, 8, 12, 13]

我当前的运行时间约为 5 µs。我对 Python 还是有点陌生​​,希望通过可能结合前两个数组或 lamdba 或我什至不知道的一些很酷的东西来找到一个快速的解决方案。

感谢阅读!

【问题讨论】:

  • 考虑到您给出的示例,您的预期输出是什么?
  • 添加到文本中,感谢您指出疏忽!
  • 支持您的问题,您现在有 15 个代表,请随时支持并接受@piRSquared 答案

标签: python arrays pandas numpy


【解决方案1】:

您可以使用searchsortedbincount -

np.bincount(np.searchsorted(categories, valcats), values)

【讨论】:

  • 如果类别数组尚未排序,您会添加什么?
  • @piRSquared 我会对其进行排序,然后将其输入到解决方案中。
  • 我更多地考虑传递sorter参数...,sorter=categories.argsort()
  • @piRSquared 涉及很多开销。不要认为这样的情况值得。
  • @hrschbck 你可以这样做:ids = np.searchsorted(categories, valcats),然后是df.groupby('ids')['values'].max().values,如果你正在寻找一种简单的方法。对于sum,您将重用idsnp.bincount(ids, values)
【解决方案2】:

@Divakar 刚刚发布了一个非常好的答案。如果您已经定义了类别数组,我会使用@Divakar 的答案。如果您还没有定义唯一值,我会使用我的。


我会使用pd.factorize 来分解类别。然后使用np.bincountweights 参数设置为values 数组

f, u = pd.factorize(valcats)
np.bincount(f, values).astype(values.dtype)

array([ 1, 12,  7, 14, 13,  8])

pd.factorize 还会在u 变量中生成唯一值。我们可以将结果与u 对齐,看看我们是否找到了正确的解决方案。

np.column_stack([u, np.bincount(f, values).astype(values.dtype)])

array([[101,   1],
       [301,  12],
       [201,   7],
       [102,  14],
       [302,  13],
       [202,   8]])

您可以使用pd.Series 使这一点更加明显

f, u = pd.factorize(valcats)
pd.Series(np.bincount(f, values).astype(values.dtype), u)

101     1
301    12
201     7
102    14
302    13
202     8
dtype: int64

为什么是pd.factorize而不是np.unique

我们本可以做到这一点

 u, f = np.unique(valcats, return_inverse=True)

但是,np.unique 对值进行排序,并在nlogn 时间运行。另一方面,pd.factorize 不排序并以线性时间运行。对于较大的数据集,pd.factorize 将主导性能。

【讨论】:

  • 不错的解决方案~+1
  • 谢谢@Wen (-:
  • 非常感谢您的解释!
  • 这是一个新问题......我有一个答案给你。
猜你喜欢
  • 1970-01-01
  • 2018-12-25
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多