2016-11-20 2 views
1

Angenommen, Sie ein Array haben:Numpy Array Bedingte Operationsmaske?

a = [ 0,1,0] [-1,2,1] [3,-4,2]

Und können Sie sagen 20 bis alles

b = [ 20, 21, 20] [ 19, 22, 21] [ 23, 16, 22]

Nun fügen Sie können sagen, dass ich die resultierende b zum ursprünglichen Array hinzufügen möchten a aber nur in Fällen, in denen a < 0 dh bei der Index [0,1] und [1,2] wo a = -1, -4 bzw. bekommen die Wert 0 sonst. Letztlich solche, die zu einer Matrix als:

c = [ 0, 0, 0] [ 18, 0, 0] [ 0, 12, 0] 18 = 19 (from b) + -1 (from a) 12 = 16 (from b) + -4 (from a)

und gehen davon aus, dass ich das in der Lage sein wollen jeden Betrieb zu erweitern (nicht nur 20 hinzufügen), so dass Sie nicht nur alle Werte filtern < 20 von Matrix c. Daher möchte ich die Matrix a als Maske für die Matrix c verwenden und die i, ja[i,j] < 0 auf Null setzen.

Ich habe eine harte Zeit, ein kurzes Beispiel dafür zu finden, wie man das mit Python macht. Ich habe gehofft, dass Sie mich vielleicht zur richtigen Implementierung einer solchen Methode leiten können.

Was ich kämpfen muss, ist dies in eine Maske und führt nur Operationen auf die beibehaltenen Werte, schließlich in c.

Vielen Dank für die Hilfe im Voraus.

Antwort

5

Wahrscheinlich so etwas wie:

(a + b)*(a<0) 

arbeiten sollten, wenn Sie in Bezug auf die Anzahl der Zwischen Arrays sehr starke Anforderungen haben.

+0

sehr elegante Lösung! – MaxU

+0

Dies ist die eleganteste Lösung. Ich kann mir nicht vorstellen, dass jemand eine sauberere Methode hat. Sehr sauber ausgeführt. Vielen Dank. – and0rsk

0

Vielleicht nicht die sauberste Lösung, aber wie wäre dies ?:

def my_mask(a, b, threshold=0): 
    c = numpy.zeros(a.shape) 
    idx = np.where(a < threshold) 
    for ii in idx: 
     c[ii[1], ii[0]] = a[ii[1], ii[0]] + b[ii[1], ii[0]] 
    return c 
+1

Für Schleifen sollten wirklich vermieden werden, wenn mit NumPy Arrays, wenn die gewünschten Operation zu tun nicht vektorisiert werden kann. –

1

Sie können dies durch eine Kombination von boolean indexing und broadcasting erreichen. Arbeiten unter Beispiel

import numpy as np 
a = np.array([[ 0,1,0],[-1,2,1],[3,-4,2]]) 
b = a+20 
c = np.zeros(a.shape) 
c[a<0] = b[a<0] + a[a<0] 

die über c als

array([[ 0., 0., 0.], 
     [ 18., 0., 0.], 
     [ 0., 12., 0.]]) 

Die einzige wichtige Zeile im Code-Schnipsel gibt, ist die letzte. Da die Einträge von a, b und c alle ausgerichtet sind, können wir sagen, dass wir nur die entsprechenden Indizes von c wollen, wo a<0 auf die Summe der Einträge in b und a wo a<0 zugewiesen werden.

+0

Das ist gut, aber nicht so elegant wie die Lösung von Thomas. Danke für die Links und den Versuch. – and0rsk

0

die Lösung unter Verwendung numpy.zeros_like Funktion:

import numpy as np 

# the initial array 
a = [[ 0,1,0], 
    [-1,2,1], 
    [3,-4,2]] 

a = np.array(a) 
b = a + 20       # after adding 20 to each element 
c = np.zeros_like(a)    # resulting matrix (filled with zeros by default) 
neg = a < 0      # indeces of negative values 
c[neg] = b[neg] + a[neg]   # overriding the needed elements 

print(c) 

Der Ausgang:

[[ 0 0 0] 
[18 0 0] 
[ 0 12 0]]