2015-06-22 7 views
5

Ecco il mio problema: manipolo le griglie 432*46*136*136 che rappresentano time*(space) racchiuse in array numpy con numpy e python. Ho un array alt, che comprende le altitudini dei punti della griglia e un altro array temp che memorizza la temperatura dei punti della griglia.Trasformazione della griglia numpy in Python utilizzando funzioni universali

è problematico per un confronto: se T1 e T2 sono due risultati, T1[t0,z0,x0,y0] e T2[t0,z0,x0,y0] rappresentano la temperatura a H1[t0,z0,x0,y0] e metri, rispettivamente. Ma voglio confrontare la temperatura dei punti alla stessa altitudine, non allo stesso punto della griglia.

Di conseguenza, desidero modificare l'asse z delle mie matrici per rappresentare l'altitudine e non il punto della griglia. Creo una funzione conv(alt[t,z,x,y]) che attribuisce un numero compreso tra -20 e 200 per ogni altitudine. Ecco il mio codice:

def interpolation_extended(self,temp,alt): 
    [t,z,x,y]=temp.shape 
    new=np.zeros([t,220,x,y]) 
    for l in range(0,t): 
     for j in range(0,z): 
      for lat in range(0,x): 
      for lon in range(0,y): 
       new[l,conv(alt[l,j,lat,lon]),lat,lon]=temp[l,j,lat,lon] 
    return new 

Ma questo richiede sicuramente troppo tempo, non posso lavorare questo. Ho provato a scriverlo usando le funzioni universali con numpy:

def interpolation_extended(self,temp,alt): 
    [t,z,x,y]=temp.shape 
    new=np.zeros([t,220,x,y]) 
    for j in range(0,z): 
     new[:,conv(alt[:,j,:,:]),:,:]=temp[:,j,:,:] 
    return new 

Ma questo non funziona. Hai qualche idea di farlo in python/numpy senza usare 4 cicli annidati?

Grazie

+0

Ciò potrebbe essere dovuto al fatto che le chiamate di funzione in Python sono costose. Precalcolando la coordinata 'conv' con ad es. Il metodo numpy 'fromfunction' potrebbe aiutare. – Ashalynd

+0

È z maggiore di 220? Se questo è il caso, posso capire perché il tuo codice si blocca. – jfish003

+0

È 'conv 'qualsiasi combinazione/funzione lineare di' alt'? Puoi dare un esempio o pubblicare il tuo codice per 'conv'? Se 'conv' può essere vettorizzato, puoi scriverlo in 1 fodera. –

risposta

3

Non posso davvero provare il codice dal momento che non ho tue matrici, ma qualcosa di simile dovrebbe fare il lavoro.

In primo luogo, invece di dichiarare conv in funzione, ottenere l'intera proiezione quota per tutti i vostri dati:

conv = np.round(alt/500.).astype(int) 

Utilizzando np.round, la versione numpys di turno, si arrotonda tutti gli elementi della matrice di vettorizzazione operazioni in C, e quindi, si ottiene un nuovo array molto rapidamente (a velocità C). La seguente linea allinea le quote per iniziare a 0, spostando tutto l'array dal suo valore minimo (nel caso, -20):

conv -= conv.min() 

linea sopra trasformerebbe tua matrice quota dal [-20, 200 ] su [0, 220] (meglio per l'indicizzazione).

Con questo, l'interpolazione può essere fatto facilmente da ottenere indici multidimensionali:

t, z, y, x = np.indices(temp.shape) 

le vettori sopra contengono tutti gli indici necessari per indicizzare il tuo matrice originale. È quindi possibile creare la nuova matrice eseguendo:

new_matrix[t, conv[t, z, y, x], y, x] = temp[t, z, y, x] 

senza alcun loop.

Fammi sapere se funziona. Potrebbe darti degli errori poiché è difficile per me testarlo senza dati, ma dovrebbe fare il lavoro.


L'esempio seguente giocattolo funziona bene:

A = np.random.randn(3,4,5) # Random 3x4x5 matrix -- your temp matrix 
B = np.random.randint(0, 10, 3*4*5).reshape(3,4,5) # your conv matrix with altitudes from 0 to 9 
C = np.zeros((3,10,5)) # your new matrix 

z, y, x = np.indices(A.shape) 
C[z, B[z, y, x], x] = A[z, y, x] 

C contiene i risultati per altitudine.

+0

Che funziona perfettamente, grazie mille. Non sapevo nemmeno della possibilità di lavorare con gli indici come vettori. Ho dovuto cambiare: 'conv = np.round (alt/500.)' a 'conv = np.round (alt/500.). Astype (int)' per usare conv come indici. –

+0

@Arnaud PROST, grazie! Già modificato. Gli indici vettoriali sono molto utili. Ad esempio: 'A [[3, 7, 8],:]' (per l'array 'A' 2D) restituirà la 4a, l'8a e la 9a riga della matrice. La risposta che usa 'np.indices' è un'estensione a ciò indicizzando tutti gli elementi di tutti gli assi in una matrice multidimensionale. –

Problemi correlati