2016-06-07 13 views
5

Ich habe ein 3-dimensionales Array, das ich mit einem 2-dimensionalen Array, das die gleichen Dimensionen wie die beiden am weitesten rechts von der 3-dimensionalen Array hat, maskieren möchte. Gibt es eine Möglichkeit, dies zu tun, ohne die folgende Schleife zu schreiben?Maske ein 3D-Array mit einer 2d-Maske in numpy

import numpy as np 

nx = 2 
nt = 4 

field3d = np.random.rand(nt, nx, nx) 
field2d = np.random.rand(nx, nx) 

field3d_mask = np.zeros(field3d.shape, dtype=bool) 

for t in range(nt): 
    field3d_mask[t,:,:] = field2d > 0.3 

field3d = np.ma.array(field3d, mask=field3d_mask) 

print field2d 
print field3d 

Antwort

6

Ohne die Schleife könnte man es schreiben als:

field3d_mask[:,:,:] = field2d[np.newaxis,:,:] > 0.3 

Zum Beispiel:

field3d_mask_1 = np.zeros(field3d.shape, dtype=bool) 
field3d_mask_2 = np.zeros(field3d.shape, dtype=bool) 

for t in range(nt): 
    field3d_mask_1[t,:,:] = field2d > 0.3 

field3d_mask_2[:,:,:] = field2d[np.newaxis,:,:] > 0.3 

print((field3d_mask_1 == field3d_mask_2).all()) 

gibt:

Wahre

5

Es gibt numpy.broadcast_to (neu in Numpy 1.10.0):

field3d_mask = np.broadcast_to(field2d > 0.3, field3d.shape) 
+1

Dies scheint viel besser (mehr numpythonic?) Als die akzeptierte Antwort. Eine Übertragung beinhaltet normalerweise kein Kopieren der Daten in n-Zeit. Es simuliert es nur, indem es einen Schritt entsprechend setzt. –

+0

Ja, in der Tat warnt die Option mit 'numpy.newaxis' in @ Bart's Antwort nun:' VisibleDeprecationWarning: Boolescher Index stimmt nicht überein indiziertem Array entlang Dimension 2; Dimension ist 3, aber die entsprechende Boolesche Dimension ist 1 ' – Benjamin

+0

@ Benjamin; mit welcher Python/Numpy Version? Ich benutze die 'np.newaxis' seit Monaten ++ jetzt mit Python 3.6.1 und Numpy 1.13.0, ohne jede Warnung. – Bart