2016-06-25 110 views
5

我有一個數組:如何通過索引在numpy中累積數組?

a = np.array([0,0,0,0,0,0]) 

我要添加一些其它數組的每個索引,而索引可以出現多於一個次。我想獲得每個索引的一些。我寫:

a[np.array([1,2,2,1,3])] += np.array([1,1,1,1,1]) 

卻得到了一個爲:

array([0, 1, 1, 1, 0, 0]) 

但我要的是得到:

array([0, 2, 2, 1, 0, 0]) 

如何實現這numpy的沒有for循環?

回答

9

使用純numpy,以及避免for循環:

np.add.at(a, np.array([1,2,2,1,3]), np.array([1,1,1,1,1])) 

輸出:

>>> a = np.array([0,0,0,0,0,0]) 
>>> np.add.at(a, np.array([1,2,2,1,3]), np.array([1,1,1,1,1])) 
>>> a 
array([0, 2, 2, 1, 0, 0]) 

請注意,這確實就地替換。這是你所期望的,但未來的觀衆可能不希望這樣做。因此,筆記:)

+1

太棒了。我甚至看過'np.add.reduceat',但我沒有花太多時間用'ufunc'方法,所以我不瞭解它們中的大部分。這裏的[documentation](http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.at.html)甚至是完美的......「對於另外的ufunc,這種方法相當於[索引] + = b,除了對索引超過一次的元素累計結果「 – mgilson

+1

謝謝,這正是我想要的。 – maple

1

你總是可以迭代自己。喜歡的東西:

for i in [1,2,2,1,3]: 
    a[i] += 1 
+1

謝謝,但我想避免循環。 – maple

1

我不知道的一個聰明的numpy的量化的方式來做到這一點...最好我能想出是:

>>> indices = np.array([1,2,2,1,3]) 
>>> values = np.array([1,1,1,1,1]) 
>>> a = np.array([0,0,0,0,0,0]) 
>>> for i, ix in enumerate(indices): 
... a[ix] += values[i] 
... 
>>> a 
array([0, 2, 2, 1, 0, 0]) 
+0

謝謝,但我想避免循環。 – maple

+2

@maple - 我明白,但我不知道有辦法做到這一點。當然,這並不是說沒有辦法做到這一點(儘管可能沒有)。無論如何,有時候有一個正確的(工作)代碼的例子足以說明問題,讓其他人能夠更好地解決問題。 – mgilson

+0

@maple檢查我的答案,如果你想知道一種方法來做到這一點。謝謝。儘管我完全贊同以不同方式解決問題的例子。 – oxalorg

1

你可以這樣做(假設每個索引有一個相關值):

a = np.array([0,0,0,0,0,0]) 
idxs = np.array([1,2,2,1,3]) 
vals = np.array([1,1,1,1,1]) 
for idx, val in zip(idxs,vals): 
    a[idx] += val