我正在使用numpy_indexed来应用矢量化的numpy bincount,如下所示:
import numpy as np
import numpy_indexed as npi
rowidx, colidx = np.indices(index_tri.shape)
(cols, rows), B = npi.count((index_tri.flatten(), rowidx.flatten()))
index_tri
以下矩阵在哪里:
index_tri = np.array([[ 0, 0, 0, 7, 1, 3],
[ 1, 2, 2, 9, 8, 9],
[ 3, 1, 1, 4, 9, 1],
[ 5, 6, 6, 10, 10, 10],
[ 7, 8, 9, 4, 3, 3],
[ 3, 8, 6, 3, 8, 6],
[ 4, 3, 3, 7, 8, 9],
[10, 10, 10, 5, 6, 6],
[ 4, 9, 1, 3, 1, 1],
[ 9, 8, 9, 1, 2, 2]])
然后,将合并的值映射到以下初始化矩阵的相应位置m
:
m = np.zeros((10,11))
m
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
m[rows, cols] = B
m
array([[3., 1., 0., 1., 0., 0., 0., 1., 0., 0., 0.],
[0., 1., 2., 0., 0., 0., 0., 0., 1., 2., 0.],
[0., 3., 0., 1., 1., 0., 0., 0., 0., 1., 0.],
[0., 0., 0., 0., 0., 1., 2., 0., 0., 0., 3.],
[0., 0., 0., 2., 1., 0., 0., 1., 1., 1., 0.],
[0., 0., 0., 2., 0., 0., 2., 0., 2., 0., 0.],
[0., 0., 0., 2., 1., 0., 0., 1., 1., 1., 0.],
[0., 0., 0., 0., 0., 1., 2., 0., 0., 0., 3.],
[0., 3., 0., 1., 1., 0., 0., 0., 0., 1., 0.],
[0., 1., 2., 0., 0., 0., 0., 0., 1., 2., 0.]])
但是,这认为index_tri
每列中每个值的权重为1。现在,如果我有一个weights数组,则为每列中提供一个相应的权重值,index_tri
而不是1:
weights = np.array([0.7, 0.8, 1.5, 0.6, 0.5, 1.9])
如何应用加权二进制计数,以便我的输出矩阵m
如下:
array([[3., 0.5, 0., 1.9, 0., 0., 0., 0.6, 0., 0., 0.],
[0., 0.7, 2.3, 0., 0., 0., 0., 0., 0.5, 2.5, 0.],
[0., 4.2, 0., 0.7, 0.6, 0., 0., 0., 0., 0.5, 0.],
[0., 0., 0., 0., 0., 0.7, 2.3, 0., 0., 0., 3.],
[0., 0., 0., 2.4, 0.6, 0., 0., 0.7, 0.8, 1.5, 0.],
[0., 0., 0., 2.3, 0., 0., 2.4, 0., 1.3, 0., 0.],
[0., 0., 0., 2.3, 0.7, 0., 0., 0.6, 0.5, 1.9, 0.],
[0., 0., 0., 0., 0., 0.6, 2.4, 0., 0., 0., 3.],
[0., 3.9, 0., 0.6, 0.7, 0., 0., 0., 0., 0.8, 0.],
[0., 0.6, 2.4, 0., 0., 0., 0., 0., 0.8, 2.2, 0.]])
任何想法?
通过使用for
循环和numpy,bincount()
我可以如下解决它:
for i in range(m.shape[0]):
m[i, :] = np.bincount(index_tri[i, :], weights=weights, minlength=m.shape[1])
我试图分别从此处和此处适应矢量化提供的解决方案,但是我无法弄清楚该ix2D
变量在第一个链接中对应的含义。如果可能的话,有人可以详细说明一下。
更新(解决方案):
基于下面的@Divakar解决方案,这是一个更新的版本,如果您的索引输入矩阵不能覆盖输出初始化矩阵的全部范围,则它需要一个额外的输入参数:
def bincount2D(id_ar_2D, weights_1D, sz=None):
# Inputs : 2D id array, 1D weights array
# Extent of bins per col
if sz == None:
n = id_ar_2D.max() + 1
N = len(id_ar_2D)
else:
n = sz[1]
N = sz[0]
# add offsets to the original values to be used when we apply raveling later on
id_ar_2D_offsetted = id_ar_2D + n * np.arange(N)[:, None]
# Finally use bincount with those 2D bins as flattened and with
# flattened b as weights. Reshaping is needed to add back into "a".
ids = id_ar_2D_offsetted.ravel()
W = np.tile(weights_1D, N)
return np.bincount(ids, W, minlength=n * N).reshape(-1, n)
受到this post
-的启发
def bincount2D(id_ar_2D, weights_1D):
# Inputs : 2D id array, 1D weights array
# Extent of bins per col
n = id_ar_2D.max()+1
N = len(id_ar_2D)
id_ar_2D_offsetted = id_ar_2D + n*np.arange(N)[:,None]
# Finally use bincount with those 2D bins as flattened and with
# flattened b as weights. Reshaping is needed to add back into "a".
ids = id_ar_2D_offsetted.ravel()
W = np.tile(weights_1D,N)
return np.bincount(ids, W, minlength=n*N).reshape(-1,n)
out = bincount2D(index_tri, weights)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句