查看: 1941|回复: 3

ValueError: the truth value of an array with multiple elements is ambiguous.U...

[复制链接]

11

主题

63

帖子

159

积分

注册会员

Rank: 2

积分
159
发表于 2018-9-20 15:44:17 | 显示全部楼层 |阅读模式
我刚刚在代码中发现了一个逻辑错误,导致了各种各样的问题。我无意中做了一个按位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: the truth value of an array with multiple elements is ambiguous.Use a.a.ny () or a.a. ll ()
为什么在使用按位操作时没有发出类似的错误 - 我该如何解决这个问题?
回复

使用道具 举报

9

主题

74

帖子

185

积分

注册会员

Rank: 2

积分
185
发表于 2018-9-20 15:45:53 | 显示全部楼层
r是一个numpy(rec)数组。所以r["dt"] >= startdate也是一个(布尔)数组。对于numpy数组,该&操作返回两个布尔数组的按位和。
该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()。
回复

使用道具 举报

19

主题

68

帖子

225

积分

论坛管理

Rank: 4

积分
225
发表于 2018-9-20 15:47:26 | 显示全部楼层
我遇到同样的问题(即使用多条件索引,它在某个日期范围内查找数据)。 (a-b).any()或(a-b).all()似乎不工作,我找到了另一种解决方案,它可以完美地满足我所需的功能(https://stackoverflow.com/questi ... element-is-ambigous -when-trying-t)。
不使用上面建议的代码,只需使用一个numpy.logical_and(a,b)就行了。在这里,将代码重写为
selected = r(logical_and(r["dt"] >= startdate, r["dt"] <= enddate))
回复

使用道具 举报

4

主题

33

帖子

88

积分

注册会员

Rank: 2

积分
88
发表于 2018-9-20 15:50:24 | 显示全部楼层
异常的原因是and隐式调用bool。首先是左操作数和(如果左操作数是True),然后是右操作数。所以x and y相当于bool(x) and bool(y)。
但是boolon 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
  1. >>> np.logical_and(arr > 1, arr < 3)
  2. array([False,  True, False], dtype=bool)

  3. >>> np.bitwise_and(arr > 1, arr < 3)
  4. array([False,  True, False], dtype=bool)

  5. >>> (arr > 1) & (arr < 3)
  6. array([False,  True, False], dtype=bool)
复制代码

和bitwise_or:
  1. >>> np.logical_or(arr <= 1, arr >= 3)
  2. array([ True, False,  True], dtype=bool)

  3. >>> np.bitwise_or(arr <= 1, arr >= 3)
  4. array([ True, False,  True], dtype=bool)

  5. >>> (arr <= 1) | (arr >= 3)
  6. array([ True, False,  True], dtype=bool)
复制代码

可以在NumPy文档中找到逻辑和二进制函数的完整列表:
•        “逻辑功能”
•        “二元操作”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表