ValueError:具有多个元素的数组的真值不明确。使用a.any()或a.all()

问题:ValueError:具有多个元素的数组的真值不明确。使用a.any()或a.all()

我刚刚在代码中发现了一个逻辑错误,该错误导致了各种各样的问题。我在无意中执行了按位AND运算,而不是逻辑AND 运算

我将代码从:

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

至:

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

令我惊讶的是,我得到了一个相当神秘的错误消息:

ValueError:具有多个元素的数组的真值不明确。使用a.any()或a.all()

为什么在使用按位操作时没有发出类似的错误-如何解决此问题?

I just discovered a logical bug in my code which was causing all sorts of problems. I was inadvertently doing a bitwise AND instead of a logical AND.

I changed the code from:

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

TO:

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

To my surprise, I got the rather cryptic error message:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Why was a similar error not emitted when I use a bitwise operation – and how do I fix this?


回答 0

r是一个numpy(rec)数组。r["dt"] >= startdate(布尔)数组也是如此。对于numpy数组,该&操作返回两个布尔数组的elementwise和。

该NumPy的开发者觉得有没有人通常理解的方式来评估布尔上下文中的数组:这可能意味着True,如果任何元素 True,或者它可能意味着True,如果所有元素True,或者True如果该数组有非0的长度,只是说出三种可能性。

由于不同的用户可能有不同的需求和不同的假设,因此NumPy开发人员拒绝猜测,而是决定在有人尝试在布尔上下文中评估数组时引发ValueError。应用于and两个numpy数组将导致两个数组在布尔上下文中求值(通过__bool__在Python3或__nonzero__Python2中调用)。

您的原始代码

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

看起来很正确。但是,如果确实需要and,则可以a and b使用(a-b).any()或代替(a-b).all()

r is a numpy (rec)array. So r["dt"] >= startdate is also a (boolean) array. For numpy arrays the & operation returns the elementwise-and of the two boolean arrays.

The NumPy developers felt there was no one commonly understood way to evaluate an array in boolean context: it could mean True if any element is True, or it could mean True if all elements are True, or True if the array has non-zero length, just to name three possibilities.

Since different users might have different needs and different assumptions, the NumPy developers refused to guess and instead decided to raise a ValueError whenever one tries to evaluate an array in boolean context. Applying and to two numpy arrays causes the two arrays to be evaluated in boolean context (by calling __bool__ in Python3 or __nonzero__ in Python2).

Your original code

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

looks correct. However, if you do want and, then instead of a and b use (a-b).any() or (a-b).all().


回答 1

我遇到了同样的问题(即使用多条件建立索引,这里是在某个日期范围内查找数据)。在(a-b).any()(a-b).all()似乎不工作,至少对我来说。

或者,我找到了另一种解决方案,该解决方案非常适合我所需的功能(尝试对数组进行索引时,包含多个元素的数组的真值不明确)。

除了使用上面建议的代码外,只需使用a即可numpy.logical_and(a,b)。在这里,您可能希望将代码重写为

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

I had the same problem (i.e. indexing with multi-conditions, here it’s finding data in a certain date range). The (a-b).any() or (a-b).all() seem not working, at least for me.

Alternatively I found another solution which works perfectly for my desired functionality (The truth value of an array with more than one element is ambigous when trying to index an array).

Instead of using suggested code above, simply using a numpy.logical_and(a,b) would work. Here you may want to rewrite the code as

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

回答 2

发生异常的原因是and隐式调用bool。首先在左侧操作数上(如果左侧操作数为True),然后在右侧操作数上。所以x and y等于bool(x) and bool(y)

然而,boolnumpy.ndarray(如果它包含多个元素)将抛出你已经看到了异常:

>>> 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()

bool()电话是隐含在and,而且在ifwhileor,所以任何的下面的示例也将失败:

>>> 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()

Python中还有更多函数和语句可以隐藏bool调用,例如,2 < x < 10这只是另一种编写方式2 < x and x < 10。而and将调用boolbool(2 < x) and bool(x < 10)

元素方面等价物and将是np.logical_and功能,同样可以使用np.logical_or等同的or

对于布尔数组-和比较喜欢的<<===!=>=>对NumPy的数组返回布尔NumPy的阵列-你也可以使用逐元素按位功能(和运营商): np.bitwise_and&运营商)

>>> 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)

bitwise_or|运算子):

>>> 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)

逻辑和二进制函数的完整列表可以在NumPy文档中找到:

The reason for the exception is that and implicitly calls bool. First on the left operand and (if the left operand is True) then on the right operand. So x and y is equivalent to bool(x) and bool(y).

However the bool on a numpy.ndarray (if it contains more than one element) will throw the exception you have seen:

>>> 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()

The bool() call is implicit in and, but also in if, while, or, so any of the following examples will also fail:

>>> 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()

There are more functions and statements in Python that hide bool calls, for example 2 < x < 10 is just another way of writing 2 < x and x < 10. And the and will call bool: bool(2 < x) and bool(x < 10).

The element-wise equivalent for and would be the np.logical_and function, similarly you could use np.logical_or as equivalent for or.

For boolean arrays – and comparisons like <, <=, ==, !=, >= and > on NumPy arrays return boolean NumPy arrays – you can also use the element-wise bitwise functions (and operators): 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)

and 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)

A complete list of logical and binary functions can be found in the NumPy documentation:


回答 3

如果您使用的pandas是为我解决问题的方法,那就是当我有NA值时我正在尝试进行计算,则解决方案是运行:

df = df.dropna()

之后,计算失败。

if you work with pandas what solved the issue for me was that i was trying to do calculations when I had NA values, the solution was to run:

df = df.dropna()

And after that the calculation that failed.


回答 4

if-statement在有数组(例如bool或int)的地方进行比较时,也会显示这种类型的错误消息。参见例如:

... code snippet ...

if dataset == bool:
    ....

... code snippet ...

此子句的数据集为数组,布尔值为“开门” … TrueFalse

如果函数包装在a中,则try-statement您将收到except Exception as error:消息,且消息中没有错误类型:

具有多个元素的数组的真值是不明确的。使用a.any()或a.all()

This typed error-message also shows while an if-statement comparison is done where there is an array and for example a bool or int. See for example:

... code snippet ...

if dataset == bool:
    ....

... code snippet ...

This clause has dataset as array and bool is euhm the “open door”… True or False.

In case the function is wrapped within a try-statement you will receive with except Exception as error: the message without its error-type:

The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()


回答 5

试试这个=> numpy.array(r)或numpy.array(yourvariable),然后跟命令比较你想要的东西。

try this=> numpy.array(r) or numpy.array(yourvariable) followed by the command to compare whatever you wish to.