从Python列表中删除一个Numpy对象

时间:2018-09-28 10:58:32

标签: python list

我有一个(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)为什么无效?

1 个答案:

答案 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总是创建一个您的数据的副本。