2014-05-16 28 views
6

Questa domanda è stata posta prima, ma la soluzione funziona solo per gli array 1D/2D e ho bisogno di una risposta più generale.python - ripetizione di array numpy senza replica dei dati

Come si crea un array ricorrente senza la replica dei dati? Questo mi sembra una cosa di uso generale, poiché aiuterebbe a vettorializzare le operazioni Python senza il colpo di memoria.

In particolare, ho una matrice (y, x), che desidero affiancare più volte per creare una matrice (z, y, x). Posso farlo con numpy.tile (array, (nz, 1,1)), ma a corto di memoria. Il mio caso specifico ha x = 1500, y = 2000, z = 700.

+1

Che cosa hai intenzione di fare con un array più grande? 'array [None,:,:]' può essere utile tanto quanto l'array affiancato. A meno che non si faccia un qualche tipo di prodotto 'punto' sulla dimensione y o x, si potrebbe ancora finire con un errore di memoria. – hpaulj

+0

Devo applicare una maschera geografica a un set di dati geofisici nel formato (tempo, y, x). Il modulo che sto usando richiede che la maschera abbia la stessa forma del set di dati, motivo per cui ho bisogno di replicare la maschera (y, x) sulla dimensione temporale. – user3644731

risposta

4

Un semplice trucco è quello di utilizzare np.broadcast_arrays per trasmettere la tua (x, y) contro un z vettore -lungo nella prima dimensione:

import numpy as np 

M = np.arange(1500*2000).reshape(1500, 2000) 
z = np.zeros(700) 

# broadcasting over the first dimension 
_, M_broadcast = np.broadcast_arrays(z[:, None, None], M[None, ...]) 

print M_broadcast.shape, M_broadcast.flags.owndata 
# (700, 1500, 2000), False 

di generalizzare il metodo stride_tricks data per un array 1D in this answer, non vi resta che includi la forma e la lunghezza della falcata per ogni dimensione della matrice di output:

M_strided = np.lib.stride_tricks.as_strided(
       M,        # input array 
       (700, M.shape[0], M.shape[1]), # output dimensions 
       (0, M.strides[0], M.strides[1]) # stride length in bytes 
      ) 
+0

La cosa trasmittente fa esattamente quello che volevo. Mi sembra più semplice/più logico del metodo stride_tricks. – user3644731

+0

Internamente 'broadcast_arrays' usa' as_strided' esattamente in questo modo. Guarda in 'numpy/lib/stride_tricks.py'. È la lunghezza del passo '0' per la prima dimensione che fa il trucco. – hpaulj

+0

La riga 'stride length in bytes' dovrebbe essere' (0, M.strides [0], M.strides [1]) ' – hpaulj