Membership for list of arrays: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() error problem

Membership for list of arrays: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() error problem

Q = [np.array([0, 1]), np.array([1, 2]), np.array([2, 3]), np.array([3, 4])]
for q in Q:
    print(q in Q)

运行 上面的代码,它在第一次迭代时给了我结果 'True',而 ValueError 随后出现。

True

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

我不知道为什么它在第二次迭代时开始出错。任何人都可以帮助我..

本质上,您不能使用 in 来测试 Python 列表中的 numpy 数组。它只会对第一个元素起作用,因为 Python 测试相等性的方式进行了优化。

发生的事情是 list.__contains__ 的实现(in 遵从),使用 short-cut 来更快地找到匹配项,首先 检查身份。大多数使用 Python 的人都知道这是 is operator。这比 == 相等性检查更快,因为所有 is 所要做的就是查看两个对象的指针是否具有相同的值,值得首先检查 .身份测试对任何 Python 对象都适用,包括 numpy 数组。

如果用 Python:

编写,实现基本上看起来像这样
def __contains__(self, needle):
    for elem in self:
        if needle is elem or needle == elem:
            return True
    return False

你的 numpy 数组列表会发生什么:

  • for q in Q,第一步:q = Q[0]

    • q in QQ.__contains__(Q[0]) 相同
      • Q[0] is self[0] => True!
  • for q in Q,第 2 步:q = Q[1]

array([False, False]) 结果 不是布尔值 ,但 if 想要一个布尔值结果,因此它被传递给(C 等价物) bool() functionbool(array([False, False])) 产生您看到的错误。

或者,手动完成:

>>> import numpy as np
>>> Q = [np.array([0, 1]), np.array([1, 2]), np.array([2, 3]), np.array([3, 4])]
>>> Q[0] is Q[0]
True
>>> Q[1] is Q[0]
False
>>> Q[1] == Q[0]
array([False, False])
>>> bool(Q[1] == Q[0])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

您必须使用 any() and numpy.array_equal() 创建不使用(正常)== 等式检查的 list.__contains__ 版本:

def list_contains_array(lst, arr):
    return any(np.array_equal(arr, elem) for elem in lst)

然后您可以使用它来为您的循环获取 True

>>> for q in Q:
...     print(list_contains_array(Q, q))
...
True
True
True
True

当您比较两个 Python 列表是否相等时,您会得到一个 TrueFalse 结果:

>>> [0, 1] == [0, 1]
True
>>> [0, 1] == [1, 2]
False

但是当你比较 numpy 数组是否相等时,结果是另一个 numpy 数组,其中每个元素 i 是比较 [=第一个数组的第 43=]i 个元素与第二个数组的第 i 个元素:

>>> np.array([0, 1]) == np.array([0, 1])
array([ True,  True])
>>> np.array([0, 1]) == np.array([1, 2])
array([False, False])

当您执行 q in Q 时,它将使用 Q 的每个元素测试 q 是否为 is,如果它们不是相同的元素,它将执行平等比较。重复此操作,直到找到“相等”匹配(标识或比较相等),在这种情况下它将 return True,否则 return False 如果找不到“相等”匹配。

qQ 的第一个元素时,就像第一次通过循环的情况一样,它首先将自己与 Q 的第一个元素进行比较,并找到 is 条件存在,因此 returns True:

>>> True if Q[0] is Q[0] or Q[0] == Q[0] else False
True

但是第二次循环,qQ的第二个元素,当它与q的第一个元素比较时,因为is条件不满足,尝试做相等比较:

>>> True if Q[1] is Q[0] or Q[1] == Q[0] else False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()