Właśnie odkryłem logiczny błąd w moim kodzie, który powodował różnego rodzaju problemy. Nieumyślnie robiłem bitowe AND zamiast logicznego AND .
Zmieniłem kod z:
r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]
DO:
r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) and (r["dt"] <= enddate))
selected = r[mask]
Ku mojemu zaskoczeniu dostałem dość tajemniczy komunikat o błędzie:
ValueError: Wartość prawdy tablicy z więcej niż jednym elementem jest niejednoznaczna. Użyj a.any () lub a.all ()
Dlaczego podobny błąd nie został wyemitowany, gdy korzystam z operacji bitowej - i jak to naprawić?
Odpowiedzi:
r
jest tablicą numpy (rec). Podobnier["dt"] >= startdate
jest z tablicą (boolowską). W przypadku tablic numpy&
operacja zwraca elementarną i dwie tablice boolowskie.Programiści NumPy uważali, że nie ma jednego powszechnie rozumianego sposobu oceny tablicy w kontekście boolowskim: może to oznaczać,
True
że dowolny element jestTrue
, lub może oznaczać,True
że wszystkie elementy sąTrue
, lubTrue
jeśli tablica ma niezerową długość, wystarczy wymienić trzy możliwości.Ponieważ różni użytkownicy mogą mieć różne potrzeby i różne założenia, programiści NumPy odmówili zgadywania i zamiast tego postanowili podnieść błąd ValueError za każdym razem, gdy ktoś próbuje ocenić tablicę w kontekście boolowskim. Zastosowanie
and
do dwóch tablic numpy powoduje, że dwie tablice są oceniane w kontekście logicznym (przez wywołanie__bool__
w Python3 lub__nonzero__
Python2).Twój oryginalny kod
wygląda poprawnie. Jeśli jednak chcesz
and
, to zamiasta and b
używać(a-b).any()
lub(a-b).all()
.źródło
np.all
inp.any
są w stanie zwarcia, argument przekazany do niej ocenia się przednp.all
czynp.any
ma szansę na zwarcia. Aby to zrobić lepiej, obecnie musisz napisać specjalny kod C / Cython podobny do tego .Miałem ten sam problem (tj. Indeksowanie z wieloma warunkami, tutaj znajduje dane w określonym zakresie dat).
(a-b).any()
Lub(a-b).all()
nie zdają pracy, przynajmniej dla mnie.Alternatywnie znalazłem inne rozwiązanie, które działa idealnie dla mojej pożądanej funkcjonalności ( wartość prawdy w tablicy z więcej niż jednym elementem jest niejednoznaczna przy próbie indeksowania tablicy ).
Zamiast używać sugerowanego kodu powyżej, po prostu użycie
numpy.logical_and(a,b)
by działałoby. Tutaj możesz przepisać kod jakoźródło
Przyczyną wyjątku jest to, że
and
niejawnie wywołujebool
. Najpierw na lewym operandzie i (jeśli lewy jestTrue
), a następnie na prawym. Więcx and y
jest równoważnabool(x) and bool(y)
.Jednak
bool
na anumpy.ndarray
(jeśli zawiera więcej niż jeden element) zgłosi wyjątek, który widziałeś:bool()
Połączenie jest ukryte wand
, ale również wif
,while
,or
, więc każdy z poniższych przykładów nie powiedzie się także:W Pythonie jest więcej funkcji i instrukcji, które ukrywają
bool
wywołania, na przykład2 < x < 10
to po prostu inny sposób pisania2 < x and x < 10
. Iand
wezwiebool
:bool(2 < x) and bool(x < 10)
.Elementem mądry odpowiednikiem
and
byłbynp.logical_and
funkcja, podobnie można użyćnp.logical_or
jako ekwiwalent zaor
.Dla tablic logicznych - i porównania podoba
<
,<=
,==
,!=
,>=
i>
na powrót logicznych NumPy tablice tablice numpy - można również użyć elementu mądry bitowe funkcje (i operatorów):np.bitwise_and
(&
Operator)oraz
bitwise_or
(|
operator):Pełna lista funkcji logicznych i binarnych znajduje się w dokumentacji NumPy:
źródło
jeśli pracujesz z
pandas
tym, co rozwiązało dla mnie problem polegał na tym, że próbowałem wykonać obliczenia, gdy miałem wartości NA, rozwiązaniem było uruchomienie:df = df.dropna()
A potem obliczenia się nie udały.
źródło
Ten wpisany komunikat o błędzie pokazuje również podczas
if-statement
porównania, gdy jest tablica i na przykład bool lub int. Zobacz na przykład:Ta klauzula ma zestaw danych jako tablicę, a bool oznacza „otwarte drzwi” ...
True
lubFalse
.W przypadku, gdy funkcja jest zawinięta wewnątrz
try-statement
, otrzymaszexcept Exception as error:
wiadomość bez jej typu błędu:źródło
spróbuj tego => numpy.array (r) lub numpy.array (twoja zmienna), a następnie polecenie, aby porównać cokolwiek chcesz.
źródło