2016-05-29 16 views
5

Ho circa 100.000 array bidimensionali in cui è necessario applicare i filtri locali. Entrambe le dimensioni hanno una dimensione uniforme e la finestra si trova su un pezzo 2x2 e sposta ulteriormente 2 pezzi, in modo che ogni elemento si trovi in ​​una finestra una volta. L'output è una matrice binaria bidimensionale della stessa dimensione e anche il mio filtro è un pezzo binario 2x2. Le parti del mio filtro che sono 0 verranno mappate a 0, le parti del mio filtro che sono tutte 1 mappano a 1 se hanno lo stesso valore e mappano a 0 se non sono tutte uguali. Ecco un esempio:Applicazione efficiente della funzione sullo spostamento dell'array numpy della finestra

Filter: 0 1  Array to filter: 1 2 3 2 Output: 0 1 0 0 
     1 0      2 3 3 3    1 0 0 0 

Certo che posso fare questo utilizzando un doppio ciclo for tuttavia questo è molto inefficiente e ci deve essere un modo migliore. Ho letto questo: Vectorized moving window on 2D array in numpy tuttavia sono incerto su come applicarlo al mio caso.

risposta

4

È possibile suddividere ciascun subarray 2x2 e quindi rimodellare in modo tale che ogni blocco con finestra diventi una riga in un array 2D. Da ogni riga, estrarre gli elementi corrispondenti alle posizioni f==1 utilizzando boolean indexing. Quindi, guarda se tutti gli elementi estratti sono identici lungo ogni riga, per darci una maschera. Utilizzare questa maschera per moltiplicare con f per l'output binario finale dopo il rimodellamento.

Quindi, assumendo f come matrice filtro e A come campo dati, un'implementazione vettorializzare per seguire tali passaggi sarebbero simili -

# Setup size parameters 
M = A.shape[0] 
Mh = M/2 
N = A.shape[1]/2 

# Reshape input array to 4D such that the last two axes represent the 
# windowed block at each iteration of the intended operation  
A4D = A.reshape(-1,2,N,2).swapaxes(1,2) 

# Determine the binary array whether all elements mapped against 1 
# in the filter array are the same elements or not 
S = (np.diff(A4D.reshape(-1,4)[:,f.ravel()==1],1)==0).all(1) 

# Finally multiply the binary array with f to get desired binary output 
out = (S.reshape(Mh,N)[:,None,:,None]*f[:,None,:]).reshape(M,-1) 

Esempio run -

1) Ingressi:

In [58]: A 
Out[58]: 
array([[1, 1, 1, 1, 2, 1], 
     [1, 1, 3, 1, 2, 2], 
     [1, 3, 3, 3, 2, 3], 
     [3, 3, 3, 3, 3, 1]]) 

In [59]: f 
Out[59]: 
array([[0, 1], 
     [1, 1]]) 

2) uscite intermedie:

In [60]: A4D 
Out[60]: 
array([[[[1, 1], 
     [1, 1]], 

     [[1, 1], 
     [3, 1]], 

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


     [[[1, 3], 
     [3, 3]], 

     [[3, 3], 
     [3, 3]], 

     [[2, 3], 
     [3, 1]]]]) 

In [61]: S 
Out[61]: array([ True, False, False, True, True, False], dtype=bool) 

3) Output finale:

In [62]: out 
Out[62]: 
array([[0, 1, 0, 0, 0, 0], 
     [1, 1, 0, 0, 0, 0], 
     [0, 1, 0, 1, 0, 0], 
     [1, 1, 1, 1, 0, 0]]) 
+0

Lo stesso approccio può essere fatto con 'np.kron (~ np.any (np.diff (A4D [..., f == 1]), -1), f) ';-) –

+0

@morningsun Ah si il' kron' per la moltiplicazione all'ultimo passo! Grazie! – Divakar

Problemi correlati