问题描述
在测试numpy数组c
是否为numpy数组CNTS
的列表的成员时:
When testing if a numpy array c
is member of a list of numpy arrays 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)
我得到:
但是,答案很明确:c
恰好是CNTS[1]
,因此c in CNTS
应该返回True!
However, the answer is rather clear: c
is exactly CNTS[1]
, so c in CNTS
should return True!
如何正确测试numpy数组是否为numpy数组列表的成员?
相同的问题会在删除时发生:
The same problem happens when removing:
CNTS.remove(c)
应用程序:测试opencv
轮廓(numpy数组)是否为轮廓列表的成员,请参见例如.
Application: test if an opencv
contour (numpy array) is member of a list of contours, see for example Remove an opencv contour from a list of contours.
推荐答案
您会收到此错误,因为in
本质上是在CNTS
的每个元素x
上调用bool(c == x)
的.引发错误的是__bool__
转换:
You are getting the error because in
essentially invokes bool(c == x)
on every element x
of CNTS
. It's the __bool__
conversion that is raising the error:
>>> 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()
删除操作同样适用,因为它会测试每个元素的相等性.
The same applies for removal, since it tests for equality with each element.
包含
解决方案是对每个比较使用np.array_equal
或应用all
方法:
The solution is to use np.array_equal
or apply the all
method to each comparison:
any(np.array_equal(c, x) for x in CNTS)
OR
any((c == x).all() for x in CNTS)
删除
要执行删除,您对元素的索引比对它的存在更感兴趣.我能想到的最快方法是使用CNTS
的元素作为比较键来遍历索引:
To perform the removal, you are more interested in the index of the element than its existence. The fastest way I can think of is to iterate over the indices, using the elements of CNTS
as comparison keys:
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)
.
This option short circuits quite nicely, and returns -1
as the default index rather than raising a StopIteration
. You can remove the argument -1
to next
if you prefer the error. If you prefer, you can replace (c == x).all()
with np.array_equal(c, x)
.
现在您可以照常删除:
del CNTS[index]
这篇关于测试numpy数组是否为numpy数组列表的成员,并将其从列表中删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!