假设numpy中有三个数组:
a = np.zeros(5)
b = np.array([3,3,3,0,0])
c = np.array([1,5,10,50,100])
b现在可以用作a和c的索引。例如:
In [142]: c[b]
Out[142]: array([50, 50, 50, 1, 1])
有没有办法用这种切片将连接到重复索引的值相加?与
a[b] = c
仅存储最后的值:
array([ 100., 0., 0., 10., 0.])
我想要这样的事情:
a[b] += c
会给出
array([ 150., 0., 0., 16., 0.])
我将非常大的矢量映射到2D矩阵上,并且非常希望避免循环......
答案 0 :(得分:2)
NumPy数组的+=
运算符根本无法按照您希望的方式运行,而且我不知道如何使它以这种方式工作。作为解决方案,我建议使用numpy.bincount()
:
>>> numpy.bincount(b, c)
array([ 150., 0., 0., 16.])
根据需要添加零。
答案 1 :(得分:0)
您可以执行以下操作:
def sum_unique(label, weight):
order = np.lexsort(label.T)
label = label[order]
weight = weight[order]
unique = np.ones(len(label), 'bool')
unique[:-1] = (label[1:] != label[:-1]).any(-1)
totals = weight.cumsum()
totals = totals[unique]
totals[1:] = totals[1:] - totals[:-1]
return label[unique], totals
并像这样使用它:
In [110]: coord = np.random.randint(0, 3, (10, 2))
In [111]: coord
Out[111]:
array([[0, 2],
[0, 2],
[2, 1],
[1, 2],
[1, 0],
[0, 2],
[0, 0],
[2, 1],
[1, 2],
[1, 2]])
In [112]: weights = np.ones(10)
In [113]: uniq_coord, sums = sum_unique(coord, weights)
In [114]: uniq_coord
Out[114]:
array([[0, 0],
[1, 0],
[2, 1],
[0, 2],
[1, 2]])
In [115]: sums
Out[115]: array([ 1., 1., 2., 3., 3.])
In [116]: a = np.zeros((3,3))
In [117]: x, y = uniq_coord.T
In [118]: a[x, y] = sums
In [119]: a
Out[119]:
array([[ 1., 0., 3.],
[ 1., 0., 3.],
[ 0., 2., 0.]])
我只是想到了这一点,它可能会更容易:
In [120]: flat_coord = np.ravel_multi_index(coord.T, (3,3))
In [121]: sums = np.bincount(flat_coord, weights)
In [122]: a = np.zeros((3,3))
In [123]: a.flat[:len(sums)] = sums
In [124]: a
Out[124]:
array([[ 1., 0., 3.],
[ 1., 0., 3.],
[ 0., 2., 0.]])