Python NumPy-使用权重对2D数组按列进行矢量化bincount

Python NumPy-使用权重对2D数组按列进行矢量化bincount,python,numpy,vectorization,Python,Numpy,Vectorization,我一直在寻找解决方案,但没有看到如何将其应用到我的结构中 我有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) 我还没有看到任何以这种方式使用索引的示例,也没有看到使用权重关键字的示例。我知道我需要把所有的东西都放到一

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

我有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)

我还没有看到任何以这种方式使用索引的示例,也没有看到使用
权重
关键字的示例。我知道我需要把所有的东西都放到一个一维数组中去矢量化,但是我正在努力想办法实现这一点。

基本思想与那些链接文章中详细讨论的一样,即创建一个二维的容器数组,每个要处理的“1D数据”都有偏移量(在本例中为每个列)。所以,考虑到这些,我们最终会得到这样的结果-

# 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

基本思想与那些链接文章中详细讨论的相同,即创建一个
2D
箱数组,每个要处理的“1D数据”都有偏移量(本例中为每个列)。所以,考虑到这些,我们最终会得到这样的结果-

# 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之间,对于基于循环的代码和建议的矢量化代码,它只需将这些值从0跳到15。如何在矢量化代码中跳过它?快速运行显示结果被移动了1(正如我所认为的)。@pstatix因此,在您的实际用例中,如果您在
ix
中有
4000
,那么您的循环代码与
np。bincount
将给出一个最小长度为
4001
的数组。因此,如果您说
a
的形状使得
M
(a.shape[0])为4000,那么您的循环代码也会抛出错误。您是否检查过您的循环代码是否与实际用例一起工作?@pstatix我怀疑您错误地初始化了
a
。确保
a
中的行数至少为
ix.max()+1
。否则,你的循环代码和建议的矢量化代码都不起作用。当您分配给
a[:n]
时,如果索引没有直接对齐,是否会有问题?例如,如果我的指数在15到4000之间呢?这使得
n=4001
,那么
a[:n]
不是从0分配到4000吗?@pstatix建议的代码应该完全模拟基于循环的代码,如果索引在15到4000之间,对于基于循环的代码和建议的矢量化代码,它只需将这些值从0跳到15。如何在矢量化代码中跳过它?快速运行显示结果被移动了1(正如我所认为的)。@pstatix因此,在您的实际用例中,如果您在
ix
中有
4000
,那么您的循环代码与
np。bincount
将给出一个最小长度为
4001
的数组。因此,如果您说
a
的形状使得
M
(a.shape[0])为4000,那么您的循环代码也会抛出错误。您是否检查过您的循环代码是否与实际用例一起工作?@pstatix我怀疑您错误地初始化了
a
。确保
a
中的行数至少为
ix.max()+1
。否则,您的循环代码和建议的矢量化代码都不起作用。发布的解决方案对您有效吗?发布的解决方案对您有效吗?