繁体   English   中英

numpy arrays 加权计数的快速方法

[英]Fast way for weighted counting of numpy arrays

我有两个形状相同的二维 numpy arrays:

idx = np.array([[1, 2, 5, 6],[1, 3, 5, 2]])
val = np.array([[0.1, 0.5, 0.3, 0.2], [0.1, 0., 0.8, 0.2]])

我知道我们可以使用np.bincount设置val作为权重:

np.bincount(idx.reshape(-1), weights=val.reshape(-1))

但这并不是我想要的。 np.bincount将零放在索引不存在的地方。 在示例中,结果是:

array([0. , 0.2, 0.7, 0. , 0. , 1.1, 0.2])

但我不希望这些额外的零用于不存在的索引。 我希望加权计数对应于np.unique(idx)

array([1, 2, 3, 5, 6])

我的预期结果是:

array([0.2, 0.7, 0., 1.1, 0.2])

任何人都有一个想法来有效地做到这一点? 我的idxval非常大,有超过 100 万个元素。

您可以有效地使用 numpy 库。

看一下这个:

output = []
for i in np.unique(idx):
    wt = (idx == i)
    if i == 0:
        zeros = wt*(idx+1)
        l = np.sum(zeros*val)
    else:
        zeros = wt*idx
        l = np.sum(zeros*val)/i
    output.append(l)
print(output)

这是相当快的。 我希望它有所帮助。

您可能知道,在 python 中使用 for 循环并不是提高效率的好主意:

您可以尝试使用 np.unique 方法对 bincount 的 output 进行索引:

>>> np.bincount(idx.reshape(-1), val.reshape(-1))[np.unique(idx)]
array([0.2, 0.7, 0. , 1.1, 0.2])

如果您只想摆脱零,这可能是最快的方法。

成功的关键在于:

  • 执行从idx到连续整数的唯一值的映射,从0开始,
  • 根据上述映射的结果计算 bincount,而不是idx本身。

执行此操作的代码(非常简洁且没有任何循环)是:

unq = np.unique(idx)
mapper = pd.Series(range(unq.size), index=unq)
np.bincount(mapper[idx.reshape(-1)], weights=val.reshape(-1))

对于您的样本数据,结果是:

array([0.2, 0.7, 0. , 1.1, 0.2])

方法一:

np.uniquereturn_inverse=True一起使用。

idx = np.array([[1, 2, 5, 6],[1, 3, 5, 2]])
val = np.array([[0.1, 0.5, 0.3, 0.2], [0.1, 0., 0.8, 0.2]])

unq,inv=np.unique(idx,return_inverse=True)
np.bincount(inv,val.reshape(-1))
# array([0.2, 0.7, 0. , 1.1, 0.2])

方法二:

使用 bincount 然后删除(真正的)零。

np.bincount(idx.reshape(-1),val.reshape(-1))[np.bincount(idx.reshape(-1)).nonzero()]
# array([0.2, 0.7, 0. , 1.1, 0.2])

哪个更好将取决于idx的分布情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM