2015-04-24 9 views
5

dire che ho un array di NumPy a, e voglio creare un nuovo array, b tale che b[i, j] è una funzione di, diciamo:filtro separabile sulla gamma NumPy

a[i-1, j-1], a[i-1, j ], a[i-1, j+1], 
a[i , j-1], a[i , j ], a[i , j+1], 
a[i+1, j-1], a[i+1, j ], a[i+1, j+1] 

Quale sarebbe il modo più veloce per fare questo?

Poiché si tratta di un filtro separabile, esiste un modo per eseguirlo in più thread? (non processi, perché dovrei copiare i dati indietro)

O sta scrivendo il codice C per bypassare il GIL obbligatorio?

Anche le soluzioni parziali (come presupponendo che la funzione sia lineare) sono benvenute.

+0

Intendi come una finestra o un filtro che si muove o si muove? l'esempio in questo collegamento è per una sommatoria per una finestra 3x3 su un array 2D http://www.johnvinyard.com/blog/?p=268 –

+0

Suona come una serie di altre domande SO, la maggior parte usando il termine 'finestre scorrevoli '(o in movimento). Sebbene la maggior parte si concentri sull'iterazione della finestra, non sulla suddivisione dell'attività tra thread o processi. – hpaulj

risposta

1

Un numpy modo idealizzato di lavorare con una finestra scorrevole come questo è di costruire una serie 4D

C.shape = (N,M,3,3) 

dove

C[i,j,:,:] = np.array([a[i-1, j-1], a[i-1, j ], a[i-1, j+1], 
         a[i , j-1], a[i , j ], a[i , j+1], 
         a[i+1, j-1], a[i+1, j ], a[i+1, j+1]]) 

e scrivere la vostra funzione fare una sorta di riduzione sull'ultimo 2 dimensioni. sum o mean sarebbe tipico, ad es.

B = C.sum(axis=(2,3)) 

Altro SO domande mostrano come utilizzare np.lib.stride_tricks.as_strided costruire una tale matrice. Ma con solo un sottoarray 3x3, potrebbe essere altrettanto veloce per fare qualcosa di simile

C = np.zeros((N,M,3,3)) 
C[:,:,0,0] = a[:-1,:-1] 
etc. 

(o utilizzare hstack e vstack nello stesso senso).

Ma una cosa carina (o forse non così bella) dell'approccio lungimirante è che non implica copiare i dati di a - è solo una vista.

Come suddividere il lavoro in pezzi, posso immaginare l'utilizzo di sezioni di C (sulle prime 2 dimensioni), ad es.

C[0:100,0:100,:,:].sum(axis=(2,3))