两个类似的数组中数组包含测试。一个通过,另一个引发 ValueError。为什么?

Two similar array-in-array containment tests. One passes, the other raises a ValueError. Why?

Moar 菜鸟 Python 个问题

我有一个 NumPy 数组列表,想测试里面是否有两个数组。控制台日志:

>>> theArray
[array([[[213, 742]]], dtype=int32), array([[[127, 740]],
       [[127, 741]],
       [[128, 742]],
       [[127, 741]]], dtype=int32)]

>>> pair[0]
array([[[213, 742]]], dtype=int32)

>>> pair[1]
array([[[124, 736]]], dtype=int32)

>>> pair[0] in theArray
True

>>> pair[1] in theArray
Traceback (most recent call last):
  File "...\pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<input>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
根据调试器,

pair[0]pair[1] 似乎具有绝对相似的特征(内容除外)。那么这两种情况有何不同呢?为什么第二个会失败而第一个不会?

这里完全使用 in 是错误的。

theArray 不是数组。这是一个列表。列表的 in 假定 == 是其元素上的等价关系,但 == 不是 NumPy 数组上的等价关系;它甚至没有 return 布尔值。这里使用in本质上是没有意义的

制作 theArray 数组无济于事,因为数组的 in 会使 basically no sense.

pair[0] in theArray 碰巧没有引发异常,因为执行了优化列表。列表尝试在 == 之前对 in 进行 is 比较,而 pair[0] 恰好与 theArray 的第一个元素完全相同,因此列表永远不会开始尝试 == 并对其 return 值感到困惑。


如果你想检查一个特定的对象obj是否是一个列表的元素之一l(不只是==-等同于其中一个元素,但实际上那个对象),使用 any(obj is element for element in l).

如果要检查 NumPy 数组是否 "equal" 与数组列表中的数组具有相同的形状和相等的元素,请使用 any(numpy.array_equal(obj, element) for element in l).

我得到了成功和失败案例的 ValueError。

正如@user2357112所说,问题是列表的元素是numpy数组,所以'in'依赖的==比较不起作用

但是你可以使用这样的结构:

any(np.all(x == p[0]) for x in theArray)