2012-02-14 26 views
1

假設在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

你可以這樣做:

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.]]) 
+0

謝謝,這個作品很棒! – brorfred 2012-02-14 23:07:45

2

NumPy數組運算符+=根本不會按照您希望的方式工作,而且我不知道如何使它以這種方式工作。作爲解決方法,我建議使用numpy.bincount()

>>> numpy.bincount(b, c) 
array([ 150., 0., 0., 16.]) 

只需根據需要附加零。

+0

感謝回答!我現在已經知道存在計數 - 對於其他實現它會非常有用。對於二維數組也可以使用這種方法嗎?我的現實世界問題由三個10^7元素向量(x-pos,y-pos,value)組成,我將其映射到二維數組。 – brorfred 2012-02-14 20:01:17

+0

@brorfred:你可以用你的'reshape()'方法重新解釋你的數組作爲一維數組,而不需要使用'reshape()'方法複製,然後應用'bincount()'。 – 2012-02-14 20:30:33