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

为什么在使用按位操作时不会发出类似的错误 – 我该如何解决?

r是一个numpy(rec)数组。 所以r["dt"] >= startdate也是一个(布尔)数组。 对于numpy数组, &操作返回按位和两个布尔数组。

NumPy的开发人员觉得在布尔上下文中没有一种常用的方法来评估一个数组:如果任何一个元素为True ,它可以表示True如果所有元素都是True ,则可以表示True如果数组的长度不为零, ,只是为了说出三种可能性。

由于不同的用户可能有不同的需求和不同的假设,NumPy开发者拒绝猜测,而是每当试图在布尔上下文中评估一个数组时,就决定抛出一个ValueError。 应用and两个numpy数组会导致两个数组在布尔上下文中进行评估(通过在Python3中调用__bool__或在Python2中调用__nonzero__)。

您的原始代码

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

看起来正确。 但是,如果您确实需要,而不是a and b使用(ab).any()(ab).all()

我有同样的问题(即多条件索引,这里是在一定的日期范围内查找数据)。 (ab).any()(ab).all()似乎不起作用,至少对我而言。

或者,我发现另一个解决方案,完美地为我所需的功能(https://stackoverflow.com/questions/12647471/the-truth-value-of-an-array-with-more-than-one-element-is-ambigous -when-t-t )。

而不是使用上面的代码,只需使用numpy.logical_and(a,b) 。 在这里你可能要重写代码

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

该例外的原因是, 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()调用隐含在,而且在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另一种方式。 而且将会调用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文档中找到:

  • “逻辑功能”
  • “二元操作”