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

x为NumPy数组。以下几点:

(x > 1) and (x < 3)

给出错误信息:

ValueError:包含多个元素的数组的真值为 模糊。使用a.any()或a.all()

我怎么解决这个问题?

1407764 次浏览

如果ab是布尔NumPy数组,&操作将返回它们的元素:

a & b

返回一个布尔数组。要将其减少为单个布尔价值,可以使用其中任何一个

(a & b).any()

(a & b).all()

注意:如果abnon-Boolean数组,请考虑改用(a - b).any()(a - b).all()


基本原理

NumPy开发人员认为在布尔上下文中没有一种普遍理解的方法来计算数组:如果任何元素是True,它可能意味着True;如果所有元素是True,它可能意味着True;如果数组长度非零,它可能意味着True,仅举三种可能性。

由于不同的用户可能有不同的需求和不同的假设 NumPy开发人员拒绝猜测,而是决定在Boolean上下文中尝试计算数组时抛出ValueError。对两个numpy数组应用and会导致这两个数组在布尔上下文中求值(通过在Python3中调用__bool__或在Python2中调用__nonzero__)

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

或者,我找到了另一个解决方案,它完全适合我想要的功能(在尝试索引数组时,具有多个元素的数组的真值是不明确的)。

与其使用上面建议的代码,不如使用:

numpy.logical_and(a, b)

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

然而,numpy.ndarray上的bool(如果它包含多个元素)将抛出你所见过的异常:

>>> 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将调用bool: bool(2 < x) and bool(x < 10)

andelement-wise等效函数将是np.logical_and函数,类似地,你可以使用np.logical_or作为or的等效函数。

对于布尔数组——以及NumPy数组上的<<===!=>=>这样的比较返回布尔NumPy数组——你也可以使用element-wise位函数(和操作符):

>>> 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文档中找到:

如果你用pandas工作,什么解决了我的问题是,我试图做计算时,我有NA值,解决方案是运行:

df = df.dropna()

在那之后,计算失败了。

此类型化错误消息还显示了当存在数组(例如bool类型或int类型)时进行if-statement比较。请看例子:

... code snippet ...


if dataset == bool:
....


... code snippet ...

此子句将dataset作为数组,bool值为“open door”。TrueFalse

如果函数被包装在try-statement中,你将收到带有except Exception as error:的没有错误类型的消息:

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

采取@ZF007的答案,这并不能从整体上回答你的问题,但可以作为同样错误的解决方案。我张贴在这里,因为我还没有找到一个直接的解决方案作为这个错误消息的答案在Stack Overflow的其他地方。

当您检查数组是否为空时,将出现错误。

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

  • < p > if np.array([1,2])[0]: print(1)——比;没有ValueError,但是:if np.array([])[0]: print(1)—>IndexError: index 0 is out of bounds for axis 0 with size 0

  • < p > if np.array([1]): print(1)——比;没有ValueError,但同样对包含许多元素的数组没有帮助。

  • < p > 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.

这样做:

  • if np.array([]).size: print(1)解决了错误。

  • 考虑@loki的注释,你也可以考虑更python化的:

    if np.array([]) is not None: print(1)

对我来说,这个错误发生在测试中,下面有错误的代码:

pixels = []
self.pixels = numpy.arange(1, 10)
self.assertEqual(self.pixels, pixels)

这段代码返回:

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

因为我不能用列表断言numpy方法排列返回的对象。

解决方案作为将numpy的排列对象转换为list,我的选择是使用toList()方法,如下所示:

pixels = []
self.pixels = numpy.arange(1, 10).toList()
self.assertEqual(self.pixels, pixels)

通常,当比较两个单个数字时,Python常规代码可以正常工作,但在数组中,有一些数字(不止一个数字)应该并行处理。

例如,让我们假设如下:

a = np.array([1, 2, 3])
b = np.array([2, 3, 4])

你想检查if b >= a: ?

因为,ab不是个位数,你实际上是说,如果b的每个元素都大于a中的类似数字,那么你应该使用以下命令:

if (b >= a).all():
print("b is greater than a!")

我遇到这个问题时,访问数据从json转储直接作为一个字典元素如下:

input_data = json.dumps({'source': 'xyz'})
get_data_source = input_data['source']

你可以用以下方法来解决它:

input_data_dict = json.loads(input_data)
get_data_source = input_data_dict['source']