2016-11-18 1 views
1

Ich habe ein paar verschachtelte for-Schleifen, die das Richtige tun (maskierte Kopie des Arrays). Allerdings ist die Performance zu langsam, und ich denke, dass es einen besseren pythonischen Weg geben muss. Das Ziel ist, mithilfe der Maske zu bestimmen, wann Daten aus der Quelle kopiert werden sollen, wobei coord als Index in die Quelle verwendet wird. Der Looping-Code, der funktioniert, ist unter:Wie man eine doppelte for-Schleife mit Maske und Indizierung ersetzt?

import numpy as np 
dest = np.zeros((4,4,2)) 
source = range(32) 
source = np.reshape(source,(4,4,2)) 
mask = np.ones((4,4),bool) 
mask[1,0] = 0 
coord = np.ones((4,4,2),int) 

for y in range (0,dest.shape[0]): 
    for x in range (0, dest.shape[1]): 
     if np.all(mask[y,x]): 
      dest[y,x] = source[coord[y,x,0], coord[y,x,1]] 

print dest 

Nach dem Laufen, sieht dest wie folgt aus:

[[[ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.]] 
[[ 0. 0.] 
    [ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.]] 
[[ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.]] 
[[ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.]]] 

source[1,1] wird auf alle dest kopiert, mit Ausnahme von dest[1,0] weil mask[1,0]-False gesetzt. Der Rest von mask ist True. Kann mir bitte jemand zeigen, wie man die Loops durch etwas effizienteres ersetzt?

+0

Suchst Du verschiedene Masken oder nur die, die Sie haben zu handhaben? Wenn Sie nur dieses tun, könnten Sie direkt ohne die Maske kopieren. Und (meistens) nicht verwandt, aber es würde mit der Lesbarkeit Ihres Codes helfen, wenn Sie die Konventionen von [PEP-8] (https://www.python.org/dev/peps/pep-0008/) oder mindestens befolgen würden benutzte Leerzeichen zwischen Funktionsparametern und vor und nach '='. Wenn Sie in mehrere Funktionen umgestaltet haben, wäre Ihr Code auch ein bisschen einfacher zu verstehen. – danielunderwood

Antwort

3

Verwenden Sie numpy.where. Sie müssen mask eine zusätzliche Dimension hinzufügen, so wird es broadcast.

dest = np.where(mask[:,:,None], source[coord[:,:,0], coord[:,:,1]], dest) 

Oder falls:

dest = np.where(mask[:,:,None], source[coord[:,:,0], coord[:,:,1]], np.zeros((4,4,2))) 
+0

Genau das habe ich gesucht. Ich habe verschiedene Dinge ausprobiert, aber es war die zusätzliche Dimension auf der Maske, die mir fehlte. – MJK

Verwandte Themen