2017-08-16 38 views
0

我想從事件的二維數組(x,y,t)中增加計數器的3D矩陣(nparray)下面 代碼工作:使用以下命令從2D索引列表(x,y,z)增加3D數組的計數器:Python Numpy Slice

TOF_cube=np.zeros((324,324,4095),np.int32) #initialise a 3d array for whole data set 

data = np.fromfile(f, dtype='<i2', count=no_I16) #read all events, x,y,t as 1D array 
data=data.reshape(events,cols) 
xpos=data[:,0] 
ypos=data[:,1] 
tpos=data[:,2] 
i=0 
while i < events:    
    TOF_cube[xpos[i],ypos[i],tpos[i]] += 1 
    i+=1 

要使用切片和索引我代替我while循環與

TOF_cube[xpos,ypos,tpos] += 1 

但是,而不是(通過while循環和獨立檢查)複製正確的4365520號事件我只記錄了4365197.

爲什麼切片方法會丟失事件?

我在while循環中使用完全相同的切片,並作爲索引的'參數'。

+0

什麼'TOF_cube.max()'爲每個方法是什麼? –

回答

3

+=如果存在重複索引,則不會添加兩次。

要獲得一個量化的方式輸出相同,你需要np.add.at

np.add.at(TOF_cube, [xpos, ypos, tpos], 1) 
+0

謝謝! 這是問題所在,謝謝!我很驚訝, 'np.add.at(TOF_cube,[xpos,ypos,tpos],1)。' 似乎比+ =版本慢很多。 (我知道我錯過了一些事件,但很少)。有人會認爲'+ ='必須做一個'IF duplicated:ignore'檢查'np.add'剛剛循環的地方。有什麼想法嗎? 謝謝 D – poolz50

+0

'+ ='構造不像'np.add.at'那樣是連續的,它是一個並行(線程)調用來增加一組內存位置。這就是爲什麼它只能一次增加任何內容(並通過'set'來運行位置以確保沒有重複),否則這些單獨的線程可能會鎖定,因爲兩個嘗試同時增加同一位內存。 –

+0

也不要忘了標記檢查,如果答案是你在找什麼。 –

-1

由於我們不確切地知道您的數據是什麼樣子,很難猜出實際問題。如果這沒有幫助,請給出一個例子,我們可以運行ourselvs(即沒有文件f)。

假設你有x_pos = [1,1,2,3,5]

a = np.zeros(10) 
for i in range(len(x_pos)): 
    a[x_pos[i]]+=1 
# gives a = array([ 0., 2., 1., 1., 0., 1., 0., 0., 0., 0.]) 

然而,其他代碼

a[x_pos]+=1 
# gives a = array([ 0., 1., 1., 1., 0., 1., 0., 0., 0., 0.]) 

因此,如果指標之一出現兩次,只在短版更新一次。檢查這是否在你的xpos等實際情況下。

PS:我做了一個稍微簡單的版本,只有一個維度,但規則保持不變。

+0

你已經確切地確定了這個問題,謝謝!完全修復建議 'np.add.at(TOF_cube,[xpos,ypos,tpos],1)' – poolz50

相關問題