当测试一个 numpy 数组 c
是否是一个 numpy 数组 CNTS
列表的成员时:
import numpy as np
c = np.array([[[ 75, 763]],
[[ 57, 763]],
[[ 57, 749]],
[[ 75, 749]]])
CNTS = [np.array([[[ 78, 1202]],
[[ 63, 1202]],
[[ 63, 1187]],
[[ 78, 1187]]]),
np.array([[[ 75, 763]],
[[ 57, 763]],
[[ 57, 749]],
[[ 75, 749]]]),
np.array([[[ 72, 742]],
[[ 58, 742]],
[[ 57, 741]],
[[ 57, 727]],
[[ 58, 726]],
[[ 72, 726]]]),
np.array([[[ 66, 194]],
[[ 51, 194]],
[[ 51, 179]],
[[ 66, 179]]])]
print(c in CNTS)
我得到:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
然而,答案很明确:c
恰好是 CNTS[1]
,所以 c in CNTS
应该返回 True!
如何正确测试一个 numpy 数组是否是 numpy 数组列表的成员?
同样的问题发生在删除时:
CNTS.remove(c)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
应用:测试 opencv
轮廓(numpy 数组)是否是轮廓列表的成员,参见示例 Remove an opencv contour from a list of contours .
最佳答案
您收到错误是因为 in
本质上对 CNTS< 的每个元素
。引发错误的是 x
调用了 bool(c == x)
/__bool__
转换:
>>> c == CNTS[1]
array([[[ True, True]],
[[ True, True]],
[[ True, True]],
[[ True, True]]])
>>> bool(_)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
这同样适用于删除,因为它测试每个元素是否相等。
遏制
解决方案是使用np.array_equal
或对每个比较应用all
方法:
any(np.array_equal(c, x) for x in CNTS)
或
any((c == x).all() for x in CNTS)
移除
要执行删除,您对元素的索引比它的存在更感兴趣。我能想到的最快的方法是迭代索引,使用 CNTS
的元素作为比较键:
index = next((i for i, x in enumerate(CNTS) if (c == x).all()), -1)
这个选项短路得很好,并返回 -1
作为默认索引,而不是引发 StopIteration
。如果您更喜欢错误,可以将参数 -1
删除到 next
。如果您愿意,可以将 (c == x).all()
替换为 np.array_equal(c, x)
。
现在您可以像往常一样删除:
del CNTS[index]
关于python - 测试 numpy 数组是否是 numpy 数组列表的成员,并将其从列表中删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53065245/