In NumPy und Pandas kann die Verwendung von numpy.ndarray oder pandas.DataFrame in bedingten Ausdrücken oder und oder Operationen einen Fehler auslösen.
ValueError: The truth value of an array with more than one element is ambiguous.
ValueError: The truth value of a Series is ambiguous.
Dieser Artikel korrigiert die Ursachen dieses Fehlers und wie SIE ihn beheben können.
- Tiefere Ursache
- Verwenden Sie all(), any(), size
- Verwenden Sie &, |, ~ anstelle von and, or, not
- Verwenden Sie &, |, ~ für elementweise boolesche/bitweise Operationen
- Klammern sind für mehrere Bedingungsausdrücke erforderlich
- Für 1 oder 0 Elemente
- Für pandas.DataFrame, pandas.Series
Beachten Sie in den meisten Fällen die following two points.
- Verwenden Sie &, |, ~ anstelle von and, or, not.
- und, oder, nicht prüfen, ob das Objekt selbst True oder False ist.
- &, |, ~ führen elementweise boolesche/bitweise Operationen aus.
- Schließen Sie beim Kombinieren mehrerer Ausdrücke jeden Ausdruck in Klammern () ein.
- &, | haben eine höhere Priorität als Vergleichsoperatoren (z. B. <).
Das Konzept ist für numpy.ndarray, pandas.DataFrame und pandas.Series dasselbe.
Im folgenden Beispielcode ist NumPy Version 1.17.3 und pandas Version 0.25.1. Beachten Sie, dass sich verschiedene Versionen unterschiedlich verhalten können.
ValueError: Der Wahrheitswert eines Arrays mit mehr als einem Element ist mehrdeutig.
Die Verwendung von numpy.ndarray of bool in Bedingungsausdrücken oder and-or-not-Operationen löst einen Fehler aus.
import numpy as np
print(np.__version__)
# 1.17.3
a_bool = np.array([True, True, True])
b_bool = np.array([True, False, False])
# if a_bool:
# pass
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
# a_bool and b_bool
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
# a_bool or b_bool
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
# not b_bool
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Die Fälle pandas.DataFrame und pandas.Series werden unten beschrieben.
Tiefere Ursache
In Python werden Objekte und Ausdrücke als boolesche Werte (True, False) in bedingten Ausdrücken und, or, not-Operationen ausgewertet.
Wenn beispielsweise eine Liste leer ist (Anzahl der Elemente ist 0), wird sie als False bewertet, andernfalls als True.
print(bool([0, 1, 2]))
# True
print(bool([]))
# False
print(not [0, 1, 2])
# False
print(not [])
# True
Das Auswerten von numpy.ndarray als Bool-Wert löst einen Fehler aus.
# bool(a_bool)
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Wie das Wort „mehrdeutig“ andeutet, ist es mehrdeutig, also SIE True oder False prüfen möchten, das Objekt selbst oder jedes Element.
Verwenden Sie all(), any(), size
Wenn Sie True oder False für das Objekt selbst überprüfen möchten, verwenden Sie all() oder any(), wie in der Fehlermeldung gezeigt.
all() gibt True zurück, wenn alle Elemente True sind, any() gibt True zurück, wenn mindestens ein Element True ist.
a_bool = np.array([True, True, True])
b_bool = np.array([True, False, False])
print(a_bool.all())
# True
print(a_bool.any())
# True
print(b_bool.all())
# False
print(b_bool.any())
# True
Außerdem kann man mit dem Größen-Attribut die Gesamtzahl der Elemente abrufen und damit prüfen, ob numpy.ndarray leer ist oder nicht.
print(a_bool.size)
# 3
print(a_bool.size == 0)
# False
Verwenden Sie &, |, ~ anstelle von and, or, not
Verwenden Sie &, |, ~ für elementweise boolesche/bitweise Operationen
If SIE elementweise AND-, OR-, NOT-Operationen durchführen möchten, verwenden SIE &, |, ~ anstelle von and, or, not. ^ (XOR) ist ebenfalls verfügbar.
Für numpy.ndarray of bool führen die Operatoren &, |, ~ und ^ elementweise AND, OR, NOT und XOR aus.
a_bool = np.array([True, True, True])
b_bool = np.array([True, False, False])
print(a_bool & b_bool)
# [ True False False]
print(a_bool | b_bool)
# [ True True True]
print(~b_bool)
# [False True True]
print(a_bool ^ b_bool)
# [False True True]
Beachten Sie, dass &, | und ~ für bitweise Operationen mit ganzzahligen Werten in Python used Werden.
Für numpy.ndarray von integer führen sie elementweise bitweise Operationen aus.
a_int = np.array([0, 1, 3]) # [0b00 0b01 0b11]
b_int = np.array([1, 0, 2]) # [0b01 0b00 0b10]
print(a_int & b_int)
# [0 0 2]
print(a_int | b_int)
# [1 1 3]
print(a_int ^ b_int)
# [1 1 1]
print(~a_int)
# [-1 -2 -4]
and, or, not und &, |, ~ werden leicht verwechselt.
und, oder, nicht prüfen, ob das Objekt selbst True oder False ist. & und | Werden für bitweise beschriebene Operationen für ganzzahlige Werte und elementweise Operationen für numpy.ndarray wie oben und Set-Operationen für set used.
Denken Sie daran, dass die englischen Wörter und oder oft in der Form if A und B: und den Symbolen & und | used Werden in anderen mathematischen Operationen used.
Klammern sind für mehrere Bedingungsausdrücke erforderlich
One Vergleichsoperation for numpy.ndarray is a numpy.ndarray from bool back.
a = np.arange(12).reshape(3, 4)
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(a > 3)
# [[False False False False]
# [ True True True True]
# [ True True True True]]
print(a % 2 == 0)
# [[ True False True False]
# [ True False True False]
# [ True False True False]]
Wie oben erwähnt, verwenden SIE & oder |, um UND oder ODER für jedes Element dieser numpy.ndarray zu berechnen statt und oder oder. Wenn Sie mehrere Bedingungen mit & oder | kombinieren, müssen Sie jeden Bedingungsausdruck in Klammern () setzen.
# print(a > 3 & a % 2 == 0)
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Das liegt daran, dass & und | haben eine höhere Priorität als Vergleichsoperatoren (z. B. <).
Das obige Beispiel würde wie folgt betrieben werden.
# print(a > (3 & (a % 2)) == 0)
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Jeder bedingte Ausdruck muss in Klammern () Eingeschlossen Werden.
print((a > 3) & (a % 2 == 0))
# [[False False False False]
# [ True False True False]
# [ True False True False]]
Beachten Sie, dass Vergleichsoperationen für viele andere Objekte als numpy.ndarray True oder False zurückgeben.
x = 10
print(x > 3)
# True
print(x % 2 == 1)
# False
und und oder werden für boolesche Operationen von True und False used. Da und oder eine geringere Priorität als Vergleichsoperatoren (zB <) haben, gibt es in diesem Fall keinen Fehler ohne Klammern. Natürlich sind auch Klammern zulässig.
print(x > 3 or x % 2 == 1)
# True
print((x > 3) or (x % 2 == 1))
# True
Für 1 oder 0 Elemente
Wenn die Anzahl der Elemente eins oder null ist, wie durch die Fehlermeldung „mehr als ein Element“ angezeigt wird, wird kein Fehler ausgelöst.
ValueError: Der Wahrheitswert eines Arrays mit mehr als einem Element ist mehrdeutig.
Wenn die Anzahl der Elemente eins ist, wird der Wert des Elements als Bool-Wert ermittelt. If das Element beispielsweise eine Ganzzahl int ist, ist es False, wenn es 0 ist, und andernfalls True.
a_single = np.array([0])
b_single = np.array([1])
c_single = np.array([2])
print(bool(a_single))
# False
print(bool(b_single))
# True
print(bool(c_single))
# True
und und oder geben entweder Objekte auf der linken oder rechten Seite anstelle von True oder False zurück.
print(b_single and c_single)
# [2]
print(c_single and b_single)
# [1]
print(b_single or c_single)
# [1]
print(c_single or b_single)
# [2]
& und | Elementweise UND und ODER zurückgeben.
print(b_single & c_single)
# [0]
print(b_single | c_single)
# [3]
not gibt elementweise NICHT zurück. ~ gibt elementweise ~ zurück (für ganze Zahlen mit Vorzeichen gibt ~x -(x + 1) zurück).
print(not a_single)
# True
print(not b_single)
# False
print(not c_single)
# False
print(~a_single)
# [-1]
print(~b_single)
# [-2]
print(~c_single)
# [-3]
Wenn die Anzahl der Elemente null ist, wird eine Warnung (DeprecationWarning) ausgegeben.
a_empty = np.array([])
print(a_empty)
# []
print(bool(a_empty))
# False
#
# /usr/local/lib/python3.7/site-packages/ipykernel_launcher.py: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.
# """Entry point for launching an IPython kernel.
Es heißt, dass es in Zukunft einen Fehler auslösen WIRD (das obige Beispiel ist Version 1.17.3), daher ist es besser, die Größe so zu verwenden, wie es in der Nachricht steht.
Für pandas.DataFrame, pandas.Series
Verwenden Sie für pandas.DataFrame wie bei numpy.ndarray & oder | für elementweise Operationen und schließen Sie sterben mehrere Bedingungen in Klammern () ein.
import pandas as pd
df = pd.DataFrame(pd.np.arange(12).reshape(3, 4), columns=['a', 'b', 'c', 'd'], index=['x', 'y', 'z'])
print(df)
# a b c d
# x 0 1 2 3
# y 4 5 6 7
# z 8 9 10 11
print((df > 3) & (df % 2 == 0))
# a b c d
# x False False False False
# y True False True False
# z True False True False
Fehler Werden ausgelöst, Wenn SIE Klammern () verwenden und/oder weglassen.
# print((df > 3) and (df % 2 == 0))
# ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
# print(df > 3 & df % 2 == 0)
# ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Auch bitweise Operationen mit skalaren Werten sind möglich.
print(df & 7)
# a b c d
# x 0 1 2 3
# y 4 5 6 7
# z 0 1 2 3
print(df | 1)
# a b c d
# x 1 1 3 3
# y 5 5 7 7
# z 9 9 11 11
Bitverschiebung <<, >> kann nicht verwendet werden.
# print(df << 1)
# TypeError: unsupported operand type(s) for <<: 'DataFrame' and 'int'
# print(df << df)
# TypeError: unsupported operand type(s) for <<: 'DataFrame' and 'DataFrame'
all()- und any()-Methoden werden ebenfalls bereitgestellt, aber beachten Sie, dass der Standardwert axis=0 ist, im Gegensatz zu numpy.ndarray. Wenn Sie ganze Elemente abdecken möchten, verwenden Sie axis=None.
print(df > 3)
# a b c d
# x False False False False
# y True True True True
# z True True True True
print((df > 3).all())
# a False
# b False
# c False
# d False
# dtype: bool
print((df > 3).all(axis=1))
# x False
# y True
# z True
# dtype: bool
print((df > 3).all(axis=None))
# False
Die Attribute empty und size werden ebenfalls bereitgestellt.
print(df.empty)
# False
df_empty = pd.DataFrame()
print(df_empty.empty)
# True
print(df.size)
# 12
print(df_empty.size)
# 0
Dasselbe vergoldet für Pandas.Serie.
pandas.Series of bool WIRD used, um Zeilen gemäß Bedingungen auszuwählen. Wie bei numpy.ndarray und pandas.DataFrame müssen Sie &, |, ~ und Klammern () verwenden.
df = pd.read_csv('data/src/sample_pandas_normal.csv')
print(df)
# name age state point
# 0 Alice 24 NY 64
# 1 Bob 42 CA 92
# 2 Charlie 18 CA 70
# 3 Dave 68 TX 70
# 4 Ellen 24 CA 88
# 5 Frank 30 NY 57
print(df['age'] < 35)
# 0 True
# 1 False
# 2 True
# 3 False
# 4 True
# 5 True
# Name: age, dtype: bool
print(~(df['state'] == 'NY'))
# 0 False
# 1 True
# 2 True
# 3 True
# 4 True
# 5 False
# Name: state, dtype: bool
print((df['age'] < 35) & ~(df['state'] == 'NY'))
# 0 False
# 1 False
# 2 True
# 3 False
# 4 True
# 5 False
# dtype: bool
df_and = df[(df['age'] < 35) & ~(df['state'] == 'NY')]
print(df_and)
# name age state point
# 2 Charlie 18 CA 70
# 4 Ellen 24 CA 88