【问题标题】:NumPy - Vectorizing bincount over 2D array column wise with weightsNumPy - 使用权重向量化二维数组列上的 bincount
【发布时间】:2020-02-03 19:34:47
【问题描述】:

我一直在寻找解决方案 herehere,但没有看到如何将其应用到我的结构中。

我有 3 个数组:一个 (M, N) 零,(P,) 索引(一些重复)和一个 (P, N) 值。

我可以通过循环来完成:

# a: (M, N)
# b: (P, N)
# ix: (M,)
for i in range(N):
    a[:, i] += np.bincount(ix, weights=b[:, i], minlength=M)

我没有看到任何以这种方式使用索引或使用weights 关键字的示例。我知道我需要将所有内容都放入一维数组中以对其进行矢量化,但是我正在努力弄清楚如何实现这一点。

【问题讨论】:

  • 发布的解决方案对您有用吗?

标签: python numpy vectorization


【解决方案1】:

基本思想与那些链接帖子中的一些详细讨论保持一致,即创建一个 2D 箱数组,每个要处理的“一维数据”具有偏移量(在这种情况下是每个列)。所以,考虑到这些,我们最终会得到这样的结果 -

# Extent of bins per col
n = ix.max()+1

# 2D bins for per col processing
ix2D = ix[:,None] + n*np.arange(b.shape[1])

# Finally use bincount with those 2D bins as flattened and with
# flattened b as weights. Reshaping is needed to add back into "a".
a[:n] += np.bincount(ix2D.ravel(), weights=b.ravel(), minlength=n*N).reshape(N,-1).T

【讨论】:

  • 好吧,我和双 ravel() 很接近。当您分配给a[:n] 时,如果索引不直接对齐会不会有问题?例如,如果我的指数从 15 到 4000 怎么办?这使得n = 4001,所以a[:n] 不是从 0 分配到 4000 吗?
  • @pstatix 建议的代码应该完全模拟您的基于循环的代码。如果您的索引在 15 到 4000 之间,那么对于基于循环的代码和建议的矢量化代码也是如此。
  • 如何在矢量化代码中跳过它?快速运行显示结果偏移了 1(正如我认为的那样)。
  • @pstatix 因此,在您的实际用例中,如果您在ix 中有4000,那么带有np.bincount 的循环代码将给出一个最小长度为4001 的数组。因此,如果您说 a 的形状使得 M (a.shape[0]) 为 4000,那么您的循环代码也会引发错误。您是否检查过您的循环代码是否适用于该实际用例?
  • @pstatix 我怀疑您错误地初始化了a。确保a 中的行数至少为ix.max()+1。否则,您的循环代码和建议的矢量化代码都不起作用。
猜你喜欢
  • 2017-03-28
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
  • 2021-08-10
  • 2018-01-09
  • 1970-01-01
相关资源
最近更新 更多