测试numpy数组是否为numpy数组列表的成员,并将其从列表中删除 [英] Test if a numpy array is a member of a list of numpy arrays, and remove it from the list

查看:142
本文介绍了测试numpy数组是否为numpy数组列表的成员,并将其从列表中删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在测试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)

我得到:

ValueError:具有多个元素的数组的真值不明确.使用a.any()或a.all()

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!

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)

ValueError:具有多个元素的数组的真值不明确.使用a.any()或a.all()

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

应用程序:测试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数组列表的成员,并将其从列表中删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆