Problem z filtrowaniem wynikowej ramki danych z or
warunkiem. Chcę, aby mój wynik df
wyodrębnił wszystkie var
wartości kolumn powyżej 0,25 i poniżej -0,25.
Ta logika poniżej daje mi dwuznaczną wartość prawdy, jednak działa, gdy podzielę filtrowanie na dwie osobne operacje. Co tu się dzieje? nie wiem, gdzie użyć sugerowanego a.empty(), a.bool(), a.item(),a.any() or a.all()
.
result = result[(result['var']>0.25) or (result['var']<-0.25)]
|
zamiastor
abs(result['var'])>0.25
Odpowiedzi:
Instrukcje
or
iand
python wymagajątruth
wartości -values. Ponieważpandas
są one uważane za niejednoznaczne, dlatego należy stosować operacje „bitowe”|
(lub) lub&
(i):Są one przeciążone dla tego rodzaju struktur danych, aby uzyskać element
or
(luband
).Aby dodać więcej wyjaśnień do tego oświadczenia:
Wyjątkiem jest generowany, gdy chcesz uzyskać
bool
tematycepandas.Series
:Co trafisz był miejscem, gdzie operator niejawnie konwertowane do argumentów
bool
(użyłeśor
ale zdarza się równieżand
,if
iwhile
):Oprócz tych 4 sprawozdania istnieje kilka funkcji Pythona, który ukryć niektóre
bool
połączenia (jakany
,all
,filter
, ...) nie są normalnie problematycznepandas.Series
, ale dla kompletności chciałem wspomnieć nich.W twoim przypadku wyjątek nie jest tak naprawdę pomocny, ponieważ nie wspomina o odpowiednich alternatywach . Do
and
ior
możesz użyć (jeśli chcesz porównania elementarne):numpy.logical_or
:lub po prostu
|
operator:numpy.logical_and
:lub po prostu
&
operator:Jeśli używasz operatorów, upewnij się, że poprawnie ustawiłeś nawias ze względu na pierwszeństwo operatora .
Istnieje kilka logicznych funkcji numpy, które powinny działać
pandas.Series
.Alternatywy wymienione w wyjątku są bardziej odpowiednie, jeśli napotkałeś je podczas wykonywania
if
lubwhile
. Wkrótce wyjaśnię każde z nich:Jeśli chcesz sprawdzić, czy Twoja seria jest pusta :
Python zwykle interpretuje
len
gth kontenerów (jaklist
,tuple
...) jako wartość prawdy, jeśli nie ma wyraźnej interpretacji boolowskiej. Więc jeśli chcesz sprawdzić jak w python, możesz zrobić:if x.size
lubif not x.empty
zamiastif x
.Jeśli
Series
zawiera jedną i tylko jedną wartość logiczną:Jeśli chcesz sprawdzić pierwszy i jedyny element swojej Serii (jak,
.bool()
ale działa nawet w przypadku treści nie boolowskich):Jeśli chcesz sprawdzić, czy wszystkie lub którekolwiek elementy nie są zerem, nie są puste lub nie są fałszywe:
źródło
and
,or
oraznot
w Pythonie. Operatorzy ci używają bezpośrednio tego, cobool
zwraca operand. I w pewien sposób Pandas / NumPy przeciążyło to już, aby podnieść,ValueError
ponieważ uważają prawdziwość takiej struktury danych za niejednoznaczną.Dla logiki logicznej użyj
&
i|
.Aby zobaczyć, co się dzieje, otrzymujesz kolumnę logów dla każdego porównania, np
Jeśli masz wiele kryteriów, otrzymasz wiele kolumn. Dlatego logika łączenia jest niejednoznaczna. Używanie
and
lubor
traktowanie każdej kolumny osobno, więc najpierw musisz zredukować tę kolumnę do pojedynczej wartości logicznej. Na przykład, aby sprawdzić, czy jakakolwiek wartość lub wszystkie wartości w każdej kolumnie są prawdziwe.Jednym skomplikowanym sposobem osiągnięcia tego samego jest spakowanie wszystkich tych kolumn razem i wykonanie odpowiedniej logiki.
Aby uzyskać więcej informacji, zobacz indeksowanie boolowskie w dokumentacji.
źródło
Cóż, pandy używają bitów „&” „|” i każdy warunek powinien być zawarty w „()”
Na przykład następujące prace
Ale to samo zapytanie bez odpowiednich nawiasów nie
źródło
Możesz też skorzystać z modułu operatora. Bardziej szczegółowe informacje znajdują się tutaj w dokumentacji Pythona
źródło
Ta doskonała odpowiedź bardzo dobrze wyjaśnia, co się dzieje i stanowi rozwiązanie. Chciałbym dodać inne rozwiązanie, które może być odpowiednie w podobnych przypadkach: przy użyciu
query
metody:Zobacz także http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-query .
(Niektóre testy z ramką danych, nad którymi obecnie pracuję, sugerują, że ta metoda jest nieco wolniejsza niż użycie operatorów bitowych na szeregu wartości logicznych: 2 ms vs. 870 µs)
Ostrzeżenie : Przynajmniej jedna sytuacja, w której nie jest to proste, polega na tym, że nazwy kolumn są wyrażeniami python. Miałem nazwie kolumny
WT_38hph_IP_2
,WT_38hph_input_2
alog2(WT_38hph_IP_2/WT_38hph_input_2)
i chciał wykonać następujące zapytanie:"(log2(WT_38hph_IP_2/WT_38hph_input_2) > 1) and (WT_38hph_IP_2 > 20)"
Uzyskałem następującą kaskadę wyjątków:
KeyError: 'log2'
UndefinedVariableError: name 'log2' is not defined
ValueError: "log2" is not a supported function
Wydaje mi się, że tak się stało, ponieważ parser zapytań próbował stworzyć coś z dwóch pierwszych kolumn zamiast identyfikować wyrażenie za pomocą nazwy trzeciej kolumny.
Możliwe obejście jest tutaj zaproponowane .
źródło
Napotkałem ten sam błąd i utknąłem na ramce danych pyspark na kilka dni, udało mi się go rozwiązać, wypełniając wartości na 0, ponieważ porównywałem wartości całkowite z 2 pól.
źródło