ValueError: De waarheidswaarde van een array met meer dan één element is dubbelzinnig. Gebruik a.any() of a.all()

Ik heb zojuist een logische bug in mijn code ontdekt die allerlei problemen veroorzaakte. Ik deed per ongeluk een bitsgewijze EN in plaats van een logische EN.

Ik heb de code gewijzigd van:

r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]

NAAR:

r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) and (r["dt"] <= enddate))
selected = r[mask]

Tot mijn verbazing kreeg ik de nogal cryptische foutmelding:

ValueError: De waarheidswaarde van een array met meer dan één element is
dubbelzinnig. Gebruik a.any() of a.all()

Waarom werd een soortgelijke fout niet weergegeven wanneer ik een bitsgewijze bewerking gebruik – en hoe los ik dit op?


Antwoord 1, autoriteit 100%

r is een numpy (rec)array. Dus r["dt"] >= startdate is ook een (boolean)
reeks. Voor numpy-arrays retourneert de bewerking & de elementwise-en van de twee
booleaanse arrays.

De NumPy-ontwikkelaars waren van mening dat er geen algemeen bekende manier was om te evalueren
een array in booleaanse context: het kan True betekenen als elk element is
True, of het kan True betekenen als alle elementen True zijn, of True als de array een lengte heeft die niet nul is, om maar drie mogelijkheden te noemen.

Omdat verschillende gebruikers verschillende behoeften en verschillende veronderstellingen kunnen hebben, is de
NumPy-ontwikkelaars weigerden te raden en besloten in plaats daarvan een ValueError te verhogen
telkens wanneer men een array in een booleaanse context probeert te evalueren. and toepassen op
twee numpy-arrays zorgt ervoor dat de twee arrays worden geëvalueerd in booleaanse context (door
aanroepen van __bool__ in Python3 of __nonzero__ in Python2).

Uw originele code

mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]

ziet er goed uit. Als u echter and wilt, gebruik dan in plaats van a and b (a-b).any() of (a-b).all().


Antwoord 2, autoriteit 31%

Ik had hetzelfde probleem (d.w.z. indexeren met meerdere voorwaarden, hier is het het vinden van gegevens in een bepaald datumbereik). De (a-b).any() of (a-b).all() lijken niet te werken, althans voor mij.

Als alternatief heb ik een andere oplossing gevonden die perfect werkt voor mijn gewenste functionaliteit (De waarheidswaarde van een array met meer dan één element is dubbelzinnig bij het indexeren van een array).

In plaats van de voorgestelde code hierboven te gebruiken, zou het gebruik van een numpy.logical_and(a,b) ook werken. Hier wil je misschien de code herschrijven als

selected  = r[numpy.logical_and(r["dt"] >= startdate, r["dt"] <= enddate)]

Antwoord 3, autoriteit 22%

De reden voor de uitzondering is dat and impliciet bool aanroept. Eerst op de linker operand en (als de linker operand True is) dan op de rechter operand. Dus x and y is gelijk aan bool(x) and bool(y).

De bool op een numpy.ndarray (als het meer dan één element bevat) zal echter de uitzondering veroorzaken die je hebt gezien:

>>> import numpy as np
>>> arr = np.array([1, 2, 3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

De bool()-aanroep is impliciet in and, maar ook in if, while, or, dus elk van de volgende voorbeelden zal ook mislukken:

>>> arr and arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> if arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> while arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> arr or arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Er zijn meer functies en instructies in Python die bool-aanroepen verbergen, bijvoorbeeld 2 < x < 10 is gewoon een andere manier om 2 < x and x < 10. En de and zullen bool aanroepen: bool(2 < x) and bool(x < 10).

Het elementsgewijs equivalent voor and zou de np.logical_and functie, op dezelfde manier zou je np.logical_or als equivalent voor or.

Voor booleaanse arrays – en vergelijkingen zoals <, <=, ==, != , >= en > op NumPy-arrays retourneren booleaanse NumPy-arrays – u kunt ook de elementgewijze bitsgewijze-functies (en operators) gebruiken : np.bitwise_and (& operator)

>>> np.logical_and(arr > 1, arr < 3)
array([False,  True, False], dtype=bool)
>>> np.bitwise_and(arr > 1, arr < 3)
array([False,  True, False], dtype=bool)
>>> (arr > 1) & (arr < 3)
array([False,  True, False], dtype=bool)

en bitwise_or (| operator):

>>> np.logical_or(arr <= 1, arr >= 3)
array([ True, False,  True], dtype=bool)
>>> np.bitwise_or(arr <= 1, arr >= 3)
array([ True, False,  True], dtype=bool)
>>> (arr <= 1) | (arr >= 3)
array([ True, False,  True], dtype=bool)

Een volledige lijst met logische en binaire functies is te vinden in de NumPy-documentatie:


Antwoord 4

als je met pandas werkt, loste het probleem voor mij op dat ik probeerde berekeningen uit te voeren terwijl ik NA-waarden had, de oplossing was om het volgende uit te voeren:

df = df.dropna()

En daarna de berekening die mislukte.


Antwoord 5

Dit getypte foutbericht wordt ook weergegeven terwijl een if-statement vergelijking wordt gedaan als er een array is en bijvoorbeeld een bool of int. Zie bijvoorbeeld:

... code snippet ...
if dataset == bool:
    ....
... code snippet ...

Deze clausule heeft een dataset als array en bool is euhm de “open deur”… True of False.

In het geval dat de functie is verpakt in een try-statement, ontvangt u met except Exception as error: het bericht zonder zijn fouttype:

De waarheidswaarde van een array met meer dan één element is dubbelzinnig. Gebruik a.any() of a.all()


Antwoord 6

Als ik het antwoord van @ZF007 overneem, dit is geen antwoord op uw vraag als geheel, maar kan de oplossing zijn voor dezelfde fout. Ik plaats het hier omdat ik geen directe oplossing heb gevonden als een antwoord op deze foutmelding elders op Stack Overflow.

De fout verschijnt wanneer u controleert of een array leeg was of niet.

  • if np.array([1,2]): print(1) –> ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().

  • if np.array([1,2])[0]: print(1) –> geen ValueError, maar: if np.array([])[0]: print(1) –> IndexError: index 0 is out of bounds for axis 0 with size 0.

  • if np.array([1]): print(1) –> geen ValueError, maar nogmaals, het zal niet helpen bij een array met veel elementen.

  • if np.array([]): print(1) –> DeprecationWarning: The truth value of an empty array is ambiguous. Returning False, but in future this will result in an error. Use 'array.size > 0' to check that an array is not empty.

Als je dit doet:

  • if np.array([]).size: print(1) heeft de fout opgelost.

Antwoord 7

probeer dit=> numpy.array(r) of numpy.array(yourvariable) gevolgd door het commando om te vergelijken wat je maar wilt.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

19 + four =

Other episodes