Ich filtere Zeilen in einem Datenrahmen nach Werten in zwei Spalten.
Aus irgendeinem Grund verhält sich der OR-Operator so, wie ich es von einem AND-Operator erwarten würde und umgekehrt.
Mein Testcode:
import pandas as pd
df = pd.DataFrame({'a': range(5), 'b': range(5) })
# let's insert some -1 values
df['a'][1] = -1
df['b'][1] = -1
df['a'][3] = -1
df['b'][4] = -1
df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a != -1) | (df.b != -1)]
print pd.concat([df, df1, df2], axis=1,
keys = [ 'original df', 'using AND (&)', 'using OR (|)',])
Und das Ergebnis:
original df using AND (&) using OR (|)
a b a b a b
0 0 0 0 0 0 0
1 -1 -1 NaN NaN NaN NaN
2 2 2 2 2 2 2
3 -1 3 NaN NaN -1 3
4 4 -1 NaN NaN 4 -1
[5 rows x 6 columns]
Wie Sie sehen können, löscht der AND
Operator jede Zeile, in der mindestens ein Wert gleich ist -1
. Andererseits OR
verlangt der Bediener, dass beide Werte gleich sind -1
, um sie fallen zu lassen. Ich würde genau das Gegenteil erwarten. Könnte jemand dieses Verhalten bitte erklären?
Ich benutze Pandas 0.13.1.
python
pandas
boolean-logic
Wojciech Walczak
quelle
quelle
df.query
undpd.eval
scheinen gut für diesen Anwendungsfall zu passen. Informationen zurpd.eval()
Funktionsfamilie, ihren Funktionen und Anwendungsfällen finden Sie unter Auswertung dynamischer Ausdrücke in Pandas mit pd.eval () .Antworten:
Das stimmt. Denken Sie daran, dass Sie die Bedingung in Bezug auf das schreiben, was Sie behalten möchten , und nicht in Bezug auf das, was Sie löschen möchten. Für
df1
:Du sagst "behalte die Zeilen, in denen
df.a
nicht -1 und istdf.b
nicht -1 ist", was dem Löschen jeder Zeile entspricht, in der mindestens ein Wert -1 ist.Für
df2
:Sie sagen "Behalte die Zeilen, in denen entweder -1 ist
df.a
oderdf.b
nicht -1", was dem Löschen von Zeilen entspricht, in denen beide Werte -1 sind.PS: Verketteter Zugriff wie
df['a'][1] = -1
kann Sie in Schwierigkeiten bringen. Es ist besser, sich daran zu gewöhnen,.loc
und zu verwenden.iloc
.quelle
DataFrame.query()
funktioniert auch hier gut.df.query('a != -1 or b != -1')
.&
und|
überand
undor
?and
undor
mit grundlegender Python-Semantik, die nicht geändert werden kann.&
und|
andererseits entsprechende spezielle Methoden haben, die ihr Verhalten steuern. (In Abfragezeichenfolgen können wir natürlich jede Analyse durchführen, die wir möchten.)df[True & False]
scheitern, aberdf[(True) & (False)]
es ist erfolgreich (in diesem Beispiel nicht getestet)Sie können query () verwenden , dh:
quelle
Eine kleine mathematische Logiktheorie hier:
"NICHT a UND NICHT b" ist dasselbe wie "NICHT (a ODER b)" , also:
"a NICHT -1 UND b NICHT -1" ist äquivalent zu "NICHT (a ist -1 ODER b ist -1)" , was entgegengesetzt (Komplement) zu "(a ist -1 ODER b ist -1)" ist .
Wenn Sie also genau das Gegenteil wünschen, sollten df1 und df2 wie folgt aussehen:
quelle