映射具有重复索引的数组?

时间:2012-02-14 18:22:45

标签: python matrix numpy scipy slice

假设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矩阵上,并且非常希望避免循环......

2 个答案:

答案 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.]])
相关问题