2016-09-26 5 views
0

Sagen wir, ich habe zwei Arrays: a = array([1,2,3,0,4,5,0]) und b = array([1,2,3,4,0,5,6]). Ich bin daran interessiert, die Instanzen zu entfernen, in denen a und b0 sind. Aber ich möchte auch die entsprechenden Instanzen aus beiden Listen entfernen. Daher möchte ich mit a = array([1,2,3,5]) und b = array([1,2,3,5]) enden. Dies liegt daran, dass a[3] == 0 und a[6] == 0, also sowohl b[3] als auch b[6] gelöscht werden. Ebenso seit b[4] == 0 wird a[4] deleted.Its auch einfach, dies zu tun für etwa zwei Arrays:Löschen von Werten aus mehreren Arrays mit einem bestimmten Wert

import numpy as np 
a = np.array([1,2,3,0,4,5,0]) 
b = np.array([1,2,3,4,0,5,6]) 

ix = np.where(b == 0) 
b = np.delete(b, ix) 
a = np.delete(a, ix) 

ix = np.where(a == 0) 
b = np.delete(b, ix) 
a = np.delete(a, ix) 

Doch diese Lösung doesnt Scale-up, wenn ich viele viele Arrays haben (was ich tun). Was wäre eine elegantere Art, dies zu tun?

Wenn ich versuche, die folgenden:

import numpy as np 

a = np.array([1,2,3,0,4,5,0]) 
b = np.array([1,2,3,4,0,5,6]) 

arrays = [a,b] 

for array in arrays: 
    ix = np.where(array == 0) 
    b = np.delete(b, ix) 
    a = np.delete(a, ix) 

ich a = array([1, 2, 3, 4]) und b = array([1, 2, 3, 0]), nicht die Antworten, die ich brauche. Irgendeine Idee, wo das falsch ist?

+0

tun alle Arrays die gleiche Länge haben? – dnalow

+0

@dnalow Ja, sie haben die gleiche Länge. – deserthiker

Antwort

1

Dies passiert, weil Sie, wenn Sie von np.delete zurückkehren, ein Array erhalten, das in b und a innerhalb der Schleife gespeichert ist. Die in der Array-Variablen gespeicherten Arrays sind jedoch Kopien, keine Referenzen. Wenn Sie die Arrays aktualisieren, indem Sie sie löschen, werden sie daher in Bezug auf die ursprünglichen Arrays gelöscht. Die erste Schleife gibt die Korrekturindizes von 0 im Array zurück, aber die zweite Schleife gibt ix als 4 zurück (siehe das ursprüngliche Array).
Wenn Sie beispielsweise die Array-Variable in jeder Iteration anzeigen, bleibt sie gleich.

Sie müssen Arrays neu zuweisen, nachdem Sie ein Array bearbeitet haben, so dass es die nächste Iteration berücksichtigt. Hier ist, wie Sie es tun würde -

a = np.array([1, 2, 3, 0, 4, 5, 0]) 
b = np.array([1, 2, 3, 4, 0, 5, 6]) 
arrays = [a,b] 
for i in range(0, len(arrays)): 
    ix = np.where(arrays[i] == 0) 
    b = np.delete(b, ix) 
    a = np.delete(a, ix) 
    arrays = [a, b] 

Natürlich können Sie automatisieren, was innerhalb der Schleife passiert. Ich wollte nur eine Erklärung geben, was passiert ist.

+0

Die Neuzuweisung ist ziemlich clever, aber würde dies nicht zu einem Copy-Paste-Problem bei der Skalierung auf größere Array-Sets oder variable Array-Größen führen? –

+0

Ich versuche, an etwas zu denken, das kein Kopieren erfordert. Vielleicht machen Sie eine Reihe von numply Arrays ... Werden Sie versuchen, zurück zu bekommen, wenn ich zufällig einen Weg finden! – Zeokav

0

Ein langsames Verfahren beinhaltet zweimal über die gesamte Liste arbeitet, zunächst eine Zwischenliste von Indizes bauen zu löschen, und dann den zweiten alle Werten an diesem Indizes zu löschen:

import numpy as np 

a = np.array([1,2,3,0,4,5,0]) 
b = np.array([1,2,3,4,0,5,6]) 

arrays = [a, b] 
vals = [] 

for array in arrays: 
    ix = np.where(array == 0) 
    vals.extend([y for x in ix for y in x.tolist()]) 

vals = list(set(vals)) 

new_array = [] 
for array in arrays: 
    new_array.append(np.delete(array, vals)) 
+0

Will das OP nicht, dass sich die Indizes nach jeder Iteration ändern? – Zeokav

+0

Sie sagen, dass sie die Elemente bei den Indizes aus beiden Listen entfernen wollen, wo mindestens eine der Listen eine 0 enthält. Und ihre Verwendung von "b [4] == 0" bedeutet, dass sie nicht unbedingt löschen wollen die "a" -Werte von "b" zuerst, bevor die "b" -Werte von "a" gelöscht werden. Für mich heißt das: "Erstellen Sie eine Liste aller Indizes und löschen Sie dann alle Werte." –

3

beide/alle Unter der Annahme, Arrays immer die gleiche Länge haben, können Sie masks verwenden:

ma = a != 0 # mask elements which are not equal to zero in a 
mb = b != 0 # mask elements which are not equal to zero in b 
m = ma * mb # assign the intersection of ma and mb to m 
print a[m], b[m] # [1 2 3 5] [1 2 3 5] 

Sie können natürlich auch in einer Zeile tun es

m = (a != 0) * (b != 0) 

Oder die inverse

ma = a == 0 
mb = b == 0 
m = ~(ma + mb) # not the union of ma and mb 
+0

war nicht vertraut mit Masken, @Christoph Terasa. Elegant! – deserthiker

0

Aufbau auf der Christoph Terasa Antwort verwenden, können Sie Array-Operationen statt für Loops verwenden:

arrays = np.vstack([a,b]) # ...long list of arrays of equal length 

zeroind = (arrays==0).max(0) 

pos_arrays = arrays[:,~zeroind] # a 2d array only containing those columns where none of the lines contained zeros 
Verwandte Themen