从一个numpy数组中删除元素的高效方法

4
什么是从一个numpy数组中删除元素的最佳方法?本质上,我需要np.delete(),其中数组的顺序并不重要。
import numpy as np
a = np.array([2,1,3])
print a
b = np.array([4,1,2,5,2,3])
b = np.delete(b, a) # doesn't work as desired
print b # want [4,5,2]

遍历大数组a的元素速度非常慢。

你为什么需要 [4,5,2]2 也在 a 中,所以它应该被移除,b 将会是 [4,5] - user707650
@Evert 是的,在您的第一种情况下,我希望 b == [4,5]。在第二种情况下,我已经知道 a 只包含 b 中的元素。 - John Crow
np.delete 的文档难道没有明确说明它是按索引而非值进行删除的吗?即使是 Python 中的 del 也是按索引进行删除的。只有 list.remove 是按值进行操作的。 - hpaulj
你好,只是好奇你是否已经在大数组上测试了发布的方法? - Divakar
@Divakar 感谢您的提醒。我已将采纳答案更改为您的答案,因为它比另一个解决方案每个数组快了2分钟,尽管它们都可以工作。感谢您的帮助! - John Crow
显示剩余5条评论
2个回答

1
这是一种使用排序的方法 -
def remove_first_match(a,b):
    sidx = b.argsort(kind='mergesort')
    unqb, idx = np.unique(b[sidx],return_index=1)
    return np.delete(b,sidx[idx[np.in1d(unqb,a)]])

示例运行 -

In [177]: a = np.array([2,1,3])
     ...: b = np.array([4,1,2,5,2,3,2,3])
     ...: 

In [178]: remove_first_match(a,b)
Out[178]: array([4, 5, 2, 2, 3])

In [179]: a = np.array([2,2,1,3])
     ...: b = np.array([4,5])
     ...: 

In [180]: remove_first_match(a,b)
Out[180]: array([4, 5])

1
你可以使用np.argmax来查找一组行或列中的第一个True元素。因此,例如,您可以通过广播方式执行此操作:
>>> a = np.array([2,1,3])
>>> b = np.array([4,1,2,5,2,3])
>>> np.delete(b, np.argmax(b == a[:, np.newaxis], axis=1))
array([4, 5, 2])

当然,就像许多numpy矢量化操作一样,速度是以分配大小为len(a) * len(b)的数组为代价的,因此根据您的输入,这可能不合适。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接