问题: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()
为什么在使用按位操作时没有发出类似的错误-如何解决此问题?
回答 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()
。
回答 1
我遇到了同样的问题(即使用多条件建立索引,这里是在某个日期范围内查找数据)。在(a-b).any()
或(a-b).all()
似乎不工作,至少对我来说。
或者,我找到了另一种解决方案,该解决方案非常适合我所需的功能(尝试对数组进行索引时,包含多个元素的数组的真值不明确)。
除了使用上面建议的代码外,只需使用a即可numpy.logical_and(a,b)
。在这里,您可能希望将代码重写为
selected = r[numpy.logical_and(r["dt"] >= startdate, r["dt"] <= enddate)]
回答 2
发生异常的原因是and
隐式调用bool
。首先在左侧操作数上(如果左侧操作数为True
),然后在右侧操作数上。所以x and y
等于bool(x) and bool(y)
。
然而,bool
在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
,while
,or
,所以任何的下面的示例也将失败:
>>> 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)
。
在元素方面等价物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)
>>> 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文档中找到:
回答 3
如果您使用的pandas
是为我解决问题的方法,那就是当我有NA值时我正在尝试进行计算,则解决方案是运行:
df = df.dropna()
之后,计算失败。
回答 4
if-statement
在有数组(例如bool或int)的地方进行比较时,也会显示这种类型的错误消息。参见例如:
... code snippet ...
if dataset == bool:
....
... code snippet ...
此子句的数据集为数组,布尔值为“开门” … True
或False
。
如果函数包装在a中,则try-statement
您将收到except Exception as error:
消息,且消息中没有错误类型:
具有多个元素的数组的真值是不明确的。使用a.any()或a.all()
回答 5
试试这个=> numpy.array(r)或numpy.array(yourvariable),然后跟命令比较你想要的东西。