Probleme beim Filtern meines Ergebnisdatenrahmens mit einer or
Bedingung. Ich möchte, dass mein Ergebnis df
alle Spaltenwerte extrahiert var
, die über 0,25 und unter -0,25 liegen.
Diese Logik gibt mir einen mehrdeutigen Wahrheitswert, funktioniert jedoch, wenn ich diese Filterung in zwei separate Operationen aufteile. Was passiert hier? Ich bin mir nicht sicher, wo ich den vorgeschlagenen verwenden soll a.empty(), a.bool(), a.item(),a.any() or a.all()
.
result = result[(result['var']>0.25) or (result['var']<-0.25)]
|
anstelle vonor
abs(result['var'])>0.25
Antworten:
Die Anweisungen
or
undand
python erforderntruth
-values. Dapandas
diese als mehrdeutig angesehen werden, sollten Sie "bitweise"|
(oder) oder&
(und) Operationen verwenden:Diese sind für diese Art von Datenstrukturen überladen, um das Element
or
(oderand
) zu erhalten.Nur um dieser Aussage eine weitere Erklärung hinzuzufügen:
Die Ausnahme wird ausgelöst , wenn Sie die bekommen
bool
von einpandas.Series
:Was Sie schlagen war ein Ort , an dem der Bediener implizit die Operanden umgewandelt
bool
(Sie verwendet ,or
aber es passiert auchand
,if
undwhile
):Neben diesen vier Aussagen gibt es mehrere Python - Funktionen , die einige verstecken
bool
Anrufe (wieany
,all
,filter
, ...) diese sind in der Regel nicht problematisch ,pandas.Series
aber der Vollständigkeit halber wollte ich diese ganz zu schweigen.In Ihrem Fall ist die Ausnahme nicht wirklich hilfreich, da sie nicht die richtigen Alternativen erwähnt . Für
and
undor
Sie können verwenden (wenn Sie elementweise Vergleiche wünschen):numpy.logical_or
::oder einfach der
|
Betreiber:numpy.logical_and
::oder einfach der
&
Betreiber:Wenn Sie die Operatoren verwenden, stellen Sie sicher, dass Sie Ihre Klammern aufgrund der Priorität des Operators richtig eingestellt haben .
Es gibt mehrere logische numpy Funktionen , die sollten arbeiten
pandas.Series
.Die in der Ausnahme genannten Alternativen sind besser geeignet, wenn Sie beim Ausführen von
if
oder auf sie gestoßen sindwhile
. Ich werde diese kurz erläutern:Wenn Sie überprüfen möchten, ob Ihre Serie leer ist :
Python interpretiert normalerweise die
len
gth von Containern (wielist
,tuple
, ...) als Wahrheitswert , wenn es keine explizite boolean Interpretation hat. Wenn Sie also die Python-ähnliche Prüfung wünschen, können Sie Folgendes tun:if x.size
oderif not x.empty
stattdessenif x
.Wenn Sie
Series
enthält einen und nur eine Booleschen Wert:Wenn Sie das erste und einzige Element Ihrer Serie überprüfen möchten (wie
.bool()
, funktioniert aber auch für nicht boolesche Inhalte):Wenn Sie überprüfen möchten, ob alle oder einige Elemente nicht Null, nicht leer oder nicht falsch sind:
quelle
and
,or
undnot
in Python. Diese Operatoren verwenden direkt, wasbool
auf den Operanden zurückgegeben wird. Und in gewisser Weise haben Pandas / NumPy das bereits überladen, um das zu erhöhen,ValueError
weil sie den Wahrheitswert einer solchen Datenstruktur für mehrdeutig halten.Verwenden Sie für die boolesche Logik
&
und|
.Um zu sehen, was passiert, erhalten Sie für jeden Vergleich eine Spalte mit Booleschen Werten, z
Wenn Sie mehrere Kriterien haben, werden mehrere Spalten zurückgegeben. Aus diesem Grund ist die Verknüpfungslogik nicht eindeutig. Wenn Sie jede Spalte separat verwenden
and
oderor
behandeln, müssen Sie diese Spalte zunächst auf einen einzelnen booleschen Wert reduzieren. Überprüfen Sie beispielsweise, ob ein Wert oder alle Werte in jeder der Spalten True sind.Ein komplizierter Weg, um dasselbe zu erreichen, besteht darin, alle diese Spalten zusammen zu komprimieren und die entsprechende Logik auszuführen.
Weitere Informationen finden Sie unter Boolesche Indizierung in den Dokumenten.
quelle
Nun, Pandas verwenden bitweise '&' '|' und jede Bedingung sollte in ein '()' eingeschlossen werden
Zum Beispiel folgende Arbeiten
Dieselbe Abfrage ohne geeignete Klammern ist jedoch nicht möglich
quelle
Alternativ können Sie auch das Operator-Modul verwenden. Weitere Informationen finden Sie hier Python-Dokumente
quelle
Diese ausgezeichnete Antwort erklärt sehr gut, was passiert und bietet eine Lösung. Ich möchte eine weitere Lösung hinzufügen, die in ähnlichen Fällen geeignet sein könnte: Verwenden der
query
Methode:Siehe auch http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-query .
(Einige Tests mit einem Datenrahmen, mit dem ich gerade arbeite, legen nahe, dass diese Methode etwas langsamer ist als die Verwendung der bitweisen Operatoren für eine Reihe von Booleschen Werten: 2 ms gegenüber 870 µs.)
Eine Warnung : Mindestens eine Situation, in der dies nicht einfach ist, besteht darin, dass Spaltennamen zufällig Python-Ausdrücke sind. Ich hatte Spalten genannt
WT_38hph_IP_2
,WT_38hph_input_2
undlog2(WT_38hph_IP_2/WT_38hph_input_2)
und wollte die folgende Abfrage ausführen:"(log2(WT_38hph_IP_2/WT_38hph_input_2) > 1) and (WT_38hph_IP_2 > 20)"
Ich habe die folgende Ausnahmekaskade erhalten:
KeyError: 'log2'
UndefinedVariableError: name 'log2' is not defined
ValueError: "log2" is not a supported function
Ich denke, dies ist passiert, weil der Abfrageparser versucht hat, etwas aus den ersten beiden Spalten zu machen, anstatt den Ausdruck mit dem Namen der dritten Spalte zu identifizieren.
Eine mögliche Abhilfe wird vorgeschlagen , hier .
quelle
Ich bin auf den gleichen Fehler gestoßen und wurde einige Tage lang mit einem Pyspark-Datenrahmen blockiert. Ich konnte ihn erfolgreich beheben, indem ich na-Werte mit 0 füllte, da ich ganzzahlige Werte aus 2 Feldern verglichen habe.
quelle