2015-10-21 46 views
3

我有一個2D布爾數組,如:NumPy的:快速計數2D布爾數組真實例項明智的

[[False, True, True], 
[True, False, True], 
[True, False, False], 
[True, True, True]] 

對於數組中的每一行,我要算真正的實例,並創建一個與原始數組具有相同形狀的新項目式數組,其中每個條目是該行中所有先前的True實例的總和。對於上面的例子,我所需的輸出是:

[[0, 0, 1], 
[0, 1, 1], 
[0, 1, 1], 
[0, 1, 2]] 

有沒有辦法在numpy的迅速做到這一點,而不是檢查每個項目在數組中,像這樣:

boolarr = np.array([[0, 1, 1], [1, 0, 1], [1, 0, 0], [1, 1, 1]], dtype=np.bool) 

newarr = np.zeros(boolarr.shape) 

for i, row in enumerate(boolarr): 
    for index, item in enumerate(row): 
     if item: 
      newarr[i][index+1:] += 1 

我的陣列是大足夠的(40 x 1260)和速度是一個因素,因爲這需要重複進行很多次。

謝謝。

回答

2

cumsum是你的朋友!這是短期的累計總和,你可以給它一個「軸」上下工夫,在你的情況下可以嘗試運行:

np.cumsum(boolarr,axis=1) - boolarr 

減法剛起飛的「當前」值。

+0

簡單,這就是我正在尋找的!謝謝 :) – MikeFenton

1

基本上你可以使用ndarray.cumsum沿着第二軸並在開始全零列前面加上。因此,當輸入數組假設A,你可以做 -

np.column_stack((np.zeros((A.shape[0],1),dtype=A.dtype),A[:,:-1].cumsum(1))) 

更多的位有效的技術。將初始化爲全零的輸出陣列,然後插入cumsumm-ED值到它,像這樣 -

out = np.zeros(A.shape,dtype=int) 
out[:,1:] = A[:,:-1].cumsum(1) 

採樣運行 -

In [30]: A 
Out[30]: 
array([[False, True, True], 
     [ True, False, True], 
     [ True, False, False], 
     [ True, True, True]], dtype=bool) 

In [31]: np.column_stack((np.zeros((A.shape[0]),dtype=A.dtype),A[:,:-1].cumsum(1))) 
Out[31]: 
array([[0, 0, 1], 
     [0, 1, 1], 
     [0, 1, 1], 
     [0, 1, 2]]) 

In [32]: out = np.zeros(A.shape,dtype=int) 
    ...: out[:,1:] = A[:,:-1].cumsum(1) 
    ...: 

In [33]: out 
Out[33]: 
array([[0, 0, 1], 
     [0, 1, 1], 
     [0, 1, 1], 
     [0, 1, 2]])