2012-05-21 10 views
8

Se ho un array come questo:Ridurre la risoluzione dell'array attraverso sommatoria

a = np.array([[ 1, 2, 3, 4], 
       [ 5 ,6, 7, 8], 
       [ 9,10,11,12], 
       [13,14,15,16]]) 

voglio 'modificare la risoluzione', e finire con una matrice più piccolo, (diciamo 2 file da 2 cols, o 2 righe per 4 colonne, ecc.). Voglio che questo cambiamento di risoluzione avvenga attraverso la sommatoria. Ho bisogno che questo funzioni con array di grandi dimensioni, il numero di righe, i cols dell'array più piccolo sarà sempre un fattore dell'array più grande.

Ridurre la matrice sopra a un array 2 a 2 si tradurrebbe in (che è quello che voglio):

[[ 14. 22.] 
[ 46. 54.]] 

Ho questa funzione che lo fa bene:

import numpy as np 

def shrink(data, rows, cols): 
    shrunk = np.zeros((rows,cols)) 
    for i in xrange(0,rows): 
     for j in xrange(0,cols): 
      row_sp = data.shape[0]/rows 
      col_sp = data.shape[1]/cols 
      zz = data[i*row_sp : i*row_sp + row_sp, j*col_sp : j*col_sp + col_sp] 
      shrunk[i,j] = np.sum(zz) 
    return shrunk 

print shrink(a,2,2) 
print shrink(a,2,1) 
#correct output: 
[[ 14. 22.] 
[ 46. 54.]] 
[[ 36.] 
[ 100.]] 

I' Ho avuto un lungo sguardo attraverso il examples, ma non riesco a trovare nulla che aiuta.

Esiste un modo più rapido per eseguire questa operazione senza ricorrere ai cicli?

+0

Se funziona correttamente, qual è la tua domanda? –

+0

@Niek de Klein - modificato per chiarire. Sto cercando un metodo più veloce per farlo. – fraxel

+0

Le persone che vogliono fare questo genere di cose tendono ad usare il modulo 'itertools', potrebbe valere la pena dare un'occhiata. – heltonbiker

risposta

21

Con il vostro esempio:

a.reshape(2,2,2,2).sum(axis=1).sum(axis=2) 

rendimenti:

array([[14, 22], 
     [46, 54]]) 

Ora creiamo una funzione generale ...

def shrink(data, rows, cols): 
    return data.reshape(rows, data.shape[0]/rows, cols, data.shape[1]/cols).sum(axis=1).sum(axis=2) 

lavori per i vostri esempi:

In [19]: shrink(a, 2,2) 
Out[19]: 
array([[14, 22], 
     [46, 54]]) 

In [20]: shrink(a, 2,1) 
Out[20]: 
array([[ 36], 
     [100]]) 
+0

Questo è incredibilmente "Numpythonic". – heltonbiker

+0

(+1) Intelligente! ... – NPE

+0

Esattamente quello che stavo cercando grazie! – fraxel

3

Sono sicuro che v'è una migliore/approccio più intelligente, senza tutti questi cicli orrendi ...

Ecco un modo per evitare esplicitamente loop su ogni elemento della data:

def shrink(data, rows, cols): 
    row_sp = a.shape[0]/rows 
    col_sp = a.shape[1]/cols 
    tmp = np.sum(data[i::row_sp] for i in xrange(row_sp)) 
    return np.sum(tmp[:,i::col_sp] for i in xrange(col_sp)) 

Sulla mia macchina, questo è circa il 30% più veloce della versione (per shrink(a, 2, 2)).

+0

+1 grazie mille, ottimo modo per farlo, ma eumiro lo ha inchiodato. – fraxel

Problemi correlati