319

我刚刚在我的代码中发现了一个导致各种问题的逻辑错误。我无意中做了按位 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()

为什么当我使用按位运算时没有发出类似的错误 - 我该如何解决这个问题?

4

7 回答 7

231

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

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

由于不同的用户可能有不同的需求和不同的假设,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()or (a-b).all()

于 2012-04-08T13:08:01.283 回答
72

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

或者,我找到了另一种非常适合我所需功能的解决方案(在尝试索引数组时,具有多个元素的数组的真值是模棱两可的)。

而不是使用上面建议的代码,只需使用 anumpy.logical_and(a,b)就可以了。在这里,您可能希望将代码重写为

selected  = r[numpy.logical_and(r["dt"] >= startdate, r["dt"] <= enddate)]
于 2012-12-16T16:36:56.020 回答
56

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

但是boolon a numpy.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, if,中whileor因此以下任何示例也将失败:

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

元素等效的 for将andnp.logical_and函数,类似地,您可以将np.logical_or其用作等效的 for 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 文档中找到:

于 2017-06-03T15:46:59.090 回答
3

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

df = df.dropna()

在那之后,计算失败了。

于 2019-03-03T18:57:07.230 回答
3

接受@ZF007 的回答,这并不能作为一个整体来回答您的问题,但可以作为相同错误的解决方案。我在这里发布它,因为我还没有在 Stack Overflow 的其他地方找到直接的解决方案来解决这个错误消息。

检查数组是否为空时会出现错误。

  • 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)--> 没有 ValueError,但是: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)--> 没有 ValueError,但对包含许多元素的数组也无济于事。

  • 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的评论,您还可以考虑更多的pythonic:

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

于 2020-11-30T23:59:54.307 回答
1

此类型的错误消息还会显示if-statement在存在数组(例如 bool 或 int)的情况下进行比较时。参见例如:

... code snippet ...

if dataset == bool:
    ....

... code snippet ...

该子句将数据集作为数组,并且 bool 是 euhm 的“开门”...TrueFalse.

如果函数包含在 a 中try-statement,您将收到except Exception as error:不带错误类型的消息:

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

于 2020-03-13T13:55:44.203 回答
-11

尝试 this=> numpy.array(r) 或 numpy.array(yourvariable) 后跟命令以比较您想要的任何内容。

于 2019-02-12T07:37:33.963 回答