所以我有這個數組,對吧?分配給數組,添加索引的多個副本
a=np.zeros(5)
我想在給定的索引處添加值,其中索引可以是重複的。
例如
a[[1, 2, 2]] += [1, 2, 3]
我想這產生array([ 0., 1., 5., 0., 0.])
,但我得到的答覆是array([ 0., 1., 3., 0., 0.])
。
我想這與多維數組和可廣播索引一起工作。有任何想法嗎?
所以我有這個數組,對吧?分配給數組,添加索引的多個副本
a=np.zeros(5)
我想在給定的索引處添加值,其中索引可以是重複的。
例如
a[[1, 2, 2]] += [1, 2, 3]
我想這產生array([ 0., 1., 5., 0., 0.])
,但我得到的答覆是array([ 0., 1., 3., 0., 0.])
。
我想這與多維數組和可廣播索引一起工作。有任何想法嗎?
您需要使用np.add.at
來解決與+=
遇到的緩衝問題(值不會累積在重複的索引處)。指定數組,索引,值這些索引在地方加入:
>>> a = np.zeros(5)
>>> np.add.at(a, [1, 2, 2], [1, 2, 3])
>>> a
array([ 0., 1., 5., 0., 0.])
at
是其他ufuncs的一部分太(乘法,除法等)。此方法也適用於多維數組。
您正在執行的操作可以看作分箱,並且在技術上更具體,您正在做加權分塊,這些值是權重,索引是分箱。對於這種分檔操作,您可以使用np.bincount
。
這裏的執行 -
import numpy as np
a=np.zeros(5) # initialize output array
idx = [1, 2, 2] # indices
vals = [1, 2, 3] # values
a[:max(idx)+1] = np.bincount(idx,vals) # finally store the bincounts
運行測試
這裏有兩組輸入的一些運行時測試datasizes比較建議bincount
基礎的方法,並在other answer
列出的add.at
基礎的方法:
Datasize#1 -
In [251]: a=np.zeros(1000)
...: idx = np.sort(np.random.randint(1,1000,(500))).tolist()
...: vals = np.random.rand(500).tolist()
...:
In [252]: %timeit np.add.at(a, idx, vals)
10000 loops, best of 3: 63.4 µs per loop
In [253]: %timeit a[:max(idx)+1] = np.bincount(idx,vals)
10000 loops, best of 3: 42.4 µs per loop
數據尺寸#2 -
In [254]: a=np.zeros(10000)
...: idx = np.sort(np.random.randint(1,10000,(5000))).tolist()
...: vals = np.random.rand(5000).tolist()
...:
In [255]: %timeit np.add.at(a, idx, vals)
1000 loops, best of 3: 597 µs per loop
In [256]: %timeit a[:max(idx)+1] = np.bincount(idx,vals)
1000 loops, best of 3: 404 µs per loop