我有一个(x,y)坐标列表:
[[120.027954 167.9987 ]
[918.95233 175.37206 ]
[918.14026 540.6017 ]
[113.1368 535.2902 ]]
我想一次删除一行:
centers = list(centers)
top_left = min(centers, key=sum)
print("top_left ", top_left)
centers.remove(top_left)
bottom_right = max(centers, key=sum)
print("bottom_right ", bottom_right)
centers.remove(bottom_right)
在上面的最后一行,我收到此错误:
('top_left ', array([120.027954, 167.9987 ], dtype=float32))
('bottom_right ', array([918.14026, 540.6017 ], dtype=float32))
centers.remove(bottom_right)
ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()
我不知道为什么centers.remove(top_left)有效,但centers.remove(bottom_right)为什么无效?
答案 0 :(得分:1)
Python remove函数经过优化,可以首先检查身份检查,然后检查是否相等。因此,对于alist.remove(item)
,首先检查item is alist[0]
(身份检查,查找内存位置),然后检查item == alist[0]
(相等检查,查看实际值)
对于numpy数组,相等性被numpy覆盖以返回每项检查。 (向量检查。np.array([1, 2]) == np.array([2, 2])
返回np.array([False, True])
。)remove函数无法处理此操作,因为它只需要一个布尔值。
身份仍然适用于numpy数组。因此,对于您的第一种情况,您很幸运,确切的元素是第一个元素。对于第二种情况,它必须检查多个元素,但是第一次进行相等性检查时,在其初始身份检查之后,它收到了布尔向量,并且没有引发“歧义”错误。
在您的特定情况下,建议您提取索引以代替您的操作,然后再使用pop。
ind = min(range(len(centers)), key=lambda ind: sum(centers[ind]))
对于其他人,最好编写一个带有循环的自定义函数,以自己检查是否相等,而不是默认使用numpy相等函数。
编辑:
在这种特殊情况下,还可以使用(优化的)内置numpy函数实现更高性能的解决方案。
summed_centers = centers.sum(axis=1)
mask = np.ones(len(summed_centers), np.bool_)
mask[[summed_centers.argmax(), summed_centers.argmin()]] = np.bool_(False)
new_centers = centers[mask]
EDIT2:
如果您现在不知道,有一个np.delete
函数可以执行相同操作,但无需显式创建掩码数组,但是文档偏爱使用掩码数组,因为np.delete
总是创建一个您的数据的副本。