2016-07-13 14 views
3

I eine Liste/Matrix von x und y-Koordinaten haben:Einträge aus Anordnungen in paralleler Weise Entfernen

x = [x1, x2, x3,...] 
y = [y1, y2, y3,...] 

Nun habe ich bestimmte Einträge basierend auf Bedingungen, beispielsweise entfernt werden soll, wird die folgenden :

for i in x: 
    if i <= 40 and i >= -40: 
     print "True" 
    else: 
     x.remove(i) 

for i in y: 
    if i <= 20 and i >=- 20: 
     print "True" 
    else: 
     y.remove(i) 

der obige Code die entsprechenden Einträge aus den Listen entfernt, aber wenn x1 entfernt wird, y1 bleibt noch in der Liste. Was ich erreichen möchte, ist, wenn x1 entfernt wird, y1 sollte auch entfernt werden. Wie kann ich das tun? Mein letztes Ziel ist es, x und y zu plotten, so dass ich dies nicht tun kann, da die Listen unterschiedliche Dimensionen haben. Ich kann auch

zeta_list = np.column_stack((x, y)) 

ein Array wie ([[x1, y1], [x2, y2], [x3, y3],...]]) zu bekommen, aber ich bin nicht sicher, wie Einträge aus diesem zu entfernen, ein if bedingten verwenden.

Danke.

Antwort

4

Formular eine boolesche Auswahlmaske:

mask = ~((x > 40) | (x < -40) | (y > 20) | (y < -20)) 

, dann Werte auszuwählen aus x und y wo mask wahr ist:

x, y = x[mask], y[mask] 

Wenn x ist ein NumPy Array, (x > 40) kehrt ein boolesches Array der gleichen Form wie x, das ist True wo die Elemente von x größer als 40 sind.

Beachten Sie die Verwendung von | für bitweise oder ~ für not (boolean Negation).


Alternativ durch De Morgan's law, könnten Sie

mask = ((x <= 40) & (x >= -40) & (y <= 20) & (y >= -20)) 

NumPy Operationen ausgeführt werden elementweise verwenden. So mask True wo auch immer ein Element der x liegt zwischen -40 und 40 und dem entsprechenden Element vony liegt zwischen -20 und 20.


Zum Beispiel

import numpy as np 
x = [-50, -50, 30, 0, 50] 
y = [-30, 0, 10, 30, 40] 

# change the lists to NumPy arrays 
x, y = np.asarray(x), np.asarray(y) 
# mask = ~((x > 40) | (x < -40) | (y > 20) | (y < -20)) 
mask = ((x <= 40) & (x >= -40) & (y <= 20) & (y >= -20)) 
x, y = x[mask], y[mask] 

Ausbeuten

In [35]: x 
Out[35]: array([30]) 

In [36]: y 
Out[36]: array([10]) 

mit

In [37]: mask 
Out[37]: array([False, False, True, False, False], dtype=bool) 
+0

Ich sehe, was Sie hier tun, aber was, wenn ich eine Koordinate wie (30,10) behalten wollte? in Ihrer Methode ist die Liste bereits numerisch geordnet? Oder würde es die Koordinaten beibehalten? Ich sollte es wirklich versuchen, obwohl – ThunderFlash

+0

Ja, es ist am besten, es selbst zu versuchen! Ich habe das Beispiel jedoch geändert, um die Richtigkeit des Ergebnisses zu überprüfen. – unutbu

+0

vielen dank! werde es ausprobieren – ThunderFlash

1

Dies sollte es tun.

for i in x1: 
    if i <= 40 and i >= -40: 
     print "True" 
     for i in y1: 
      if i <=20 and i >=-20: 
       print "True" 
      else: 
       x1.remove(i) 
       y1.remove(i) 
    else: 
     x1.remove(i) 
     y1.remove(i) 

Hoffe, das hat geholfen!

Danke!

+0

basicly alles, was ich war das zweite for-Schleife in die bewegt hat Zuerst, und entfernte beide Koordinaten, wenn 1 ist flase –

+1

Ich sehe die Logik dahinter, aber wenn ich den Code ausprobiert, bekomme ich diesen Fehler, ValueError: list.remove (x): x nicht in der Liste – ThunderFlash

+0

yeah ich habe es nicht , da sind einige Fehler drin, ich bin Ying, um es herauszufinden –

3

Eine weitere Option ist mit list-comprehension zu arbeiten:

Eingang:

x = [50, 10, -50, 30, 5, 6] 
y = [2, 40, 10, 5, 3, 5] 

-Code:

x, y = list(zip(*[(x, y) for x, y in zip(x, y) if x <= 40 and x > -40 and y <= 20 and y > -20])) 

Ausgang:

x 
# (30, 5, 6) 

y 
# (5, 3, 5) 
+0

Vielen Dank! Etwas Neues gelernt! – ThunderFlash

+0

Der Aufruf der eingebauten 'list()' hat keinen Einfluss auf 'x' und' y'.In der Tat, wenn Sie es loswerden die Ausgangstupel sind genau das gleiche. Wenn Sie möchten, dass 'x' und' y' Listen sind, sollten Sie Ihren Code wie folgt verändern: 'x, y = map (list, zip (* [(x, y) für x, y in zip (x, y) wenn x <= 40 and x > -40 und y <= 20 and y > -20])) ' – Tonechas

+0

Ich sehe..danke viel .. – ThunderFlash

3

Try this:

mask = ((x <= 40) & (x >= -40) & (y <= 20) & (y >= -20)) 
x, y = x[mask], y[mask] 

NumPy diese Operationen vektorisiert werden, so sollte es sehr effizient sein.

This Blogpost könnte hilfreich sein, und hier ist das Handbuch für np.where(), die einige ähnliche Beispiele zeigt.

+0

Vielen Dank, war hilfreich! – ThunderFlash

+0

Versucht, aber ich bekomme einen Fehler, der TypeError sagt: List-Indizes müssen Ganzzahlen sein, nicht Tupel – ThunderFlash

+0

Ah, Ihre Arrays müssen in einer anderen Form oder einem anderen Typ sein, als ich erwartet hatte. Kein Problem, froh, dass es geholfen hat. Wenn Sie zeigen, wie Beispieleingabearrays erstellt werden, kann ich sie überarbeiten. Aber ich mag @ unutbu's Antwort und du solltest das tun :) – Will

0

Der Vollständigkeit halber ist hier eine Lösung basierend auf itertools.

Betrachten Sie die folgenden Listen von Koordinaten:

x = [-50, -50, -10, 0, 10, 50, 50, -10, -10, 0, 10, 40] 
y = [-50, -20, -50, 50, -50, 20, 50, -20, -10, 0, 20, 10] 

Unser Ziel ist es, eine boolean Maske mit dem Wert True in diesem Indizes n für die x[n] und y[n] liegt in bestimmten Intervallen und False an anderer Stelle einzurichten. Die Intervalle Grenzen sind:

xmin, xmax = -40, 40 
ymin, ymax = -20, 20 

Wir schaffen können, eine solche Maske durch eine Liste Verständnis:

mask = [xmin <= i <= xmax and ymin <= j <= ymax for (i, j) in zip(x, y)] 

Der Boolesche Ausdruck xmin <= i <= xmax and ymin <= j <= ymax für jedes Paar von entsprechenden Koordinaten ausgewertet wird. Wenn sowohl i als auch j zu den angegebenen Intervallen gehören, wird der Ausdruck andernfalls als True und False ausgewertet. Die Tatsache, dass Vergleiche in Python verkettet werden können, macht diesen booleschen Ausdruck ziemlich kompakt und lesbar.

Schließlich können wir von denen Paare koordinieren loszuwerden, die außerhalb der Grenzen fallen mit der Funktion itertools.compress():

from itertools import compress 
x_clipped = list(compress(x, mask)) 
y_clipped = list(compress(y, mask)) 

Demo:

In [117]: mask 
Out[117]: [False, False, False, False, False, False, False, True, True, True, True, True] 

In [118]: x_clipped 
Out[118]: [-10, -10, 0, 10, 40] 

In [119]: y_clipped 
Out[119]: [-20, -10, 0, 20, 10] 
+0

Danke, war eine ganz klare Erklärung! – ThunderFlash

+0

Leider scheint der anonyme Downvoter nicht so zu denken ... – Tonechas

Verwandte Themen