Python 从一个数组中删除另一个数组中的所有数字

Python 从一个数组中删除另一个数组中的所有数字,python,arrays,numpy,Python,Arrays,Numpy,我有一个数组“removable”,其中包含来自另一个数组“All”的一些数字,该数组包含从0到k的所有数字 我想删除列表中列出的所有数字 All = np.arange(k) removable = np.ndarray([1, 3, 4 , 7, 9, ..., 200]) for i in removable: if i in All: All.remove(i) ndarray没有remove属性,但我确信numpy中有一个简单的方法来解决这个问题,但我在纪录

我有一个数组“removable”,其中包含来自另一个数组“All”的一些数字,该数组包含从0到k的所有数字

我想删除列表中列出的所有数字

All = np.arange(k)
removable = np.ndarray([1, 3, 4 , 7, 9, ..., 200])

for i in removable:
    if i in All:
        All.remove(i)

ndarray没有remove属性,但我确信numpy中有一个简单的方法来解决这个问题,但我在纪录片中找不到它。

您可以使用numpy中的函数:

>>> a = np.array([1, 2, 3, 2, 4, 1])
>>> b = np.array([3, 4, 5, 6])
>>> np.setdiff1d(a, b)
array([1, 2])

numpy数组具有固定的形状,不能从中删除元素


使用Ndarray无法执行此操作。

您应该使用集合而不是列表/数组执行此操作,这非常简单:

remaining = np.array(set(arr).difference(removable))
其中
arr
是上面的
All
数组(“All”是一个关键字,不应被覆盖)

诚然,如果
arr
中有重复的元素,那么使用集合将消除重复的元素,但听起来
arr
只是一系列唯一的值。集合具有更高效的成员身份检查(恒定时间与N阶),因此您可以更快地进行。相比之下,我制作了一个列表版本,如果值不在
removable
中,它将构建一个列表:

def remove_list(arr, rem):
    result = []
    for i in arr:
        if i not in rem:
            result.append(i)
    return result
并使我的set版本也成为一个功能:

def remove_set(arr, rem):
    return np.array(set(arr).difference(rem))
arr=np.arange(10000)
removable=np.random.randint(0,10000,1000)
的定时比较:


Set速度快50倍。

解决方案对于大型阵列,速度快,无需转换为列表(降低计算速度)

np.setdiff1d()
将消除原始条目的重复,并将返回排序结果

在某些情况下,这很好,但如果您想避免这两个方面中的一个或两个,请查看带有(反转)布尔掩码的
np.inad()

>>> a = np.array([1, 2, 3, 2, 4, 1])                                                                                                                                                                                                                    
>>> b = np.array([3, 4, 5, 6])                                                                                                                                                                                                                          
>>> a[~np.in1d(a, b)]                                                                                                                                                                                                                                   
array([1, 2, 2, 1])
>>> np.in1d(a, b)                                                                                                                                                                                                                                       
array([False, False,  True, False,  True, False])

>>> ~np.in1d(a, b)                                                                                                                                                                                                                                      
array([ True,  True, False,  True, False,  True])
~
运算符在布尔掩码上执行反转操作:

>>> a = np.array([1, 2, 3, 2, 4, 1])                                                                                                                                                                                                                    
>>> b = np.array([3, 4, 5, 6])                                                                                                                                                                                                                          
>>> a[~np.in1d(a, b)]                                                                                                                                                                                                                                   
array([1, 2, 2, 1])
>>> np.in1d(a, b)                                                                                                                                                                                                                                       
array([False, False,  True, False,  True, False])

>>> ~np.in1d(a, b)                                                                                                                                                                                                                                      
array([ True,  True, False,  True, False,  True])
免责声明:


请注意,正如您在问题中所指出的,这并不是真正的移除;结果是一个被过滤到原始数组
a
中的元素。同样的情况也会发生;NumPy数组没有就地删除元素的概念。

为什么不使用列表?我从另一个方法中获得了可删除元素,很遗憾我无法更改它。请注意,这将消除
a
中的原始条目的重复(不是由问题中的伪代码完成),结果将被分类为正确,但是np.arange(k)提供一个没有重复项的列表。我的答案不适用于重复项。噢,snap,
setdiff1d
甚至比显式集合转换和差分更快。我想这是有道理的,可能更优化了。我不知道numpy有这个!现在的问题是OP是否需要复制或重复数据消除
np.isin()
调用
np.asarray()
+
np.inad()
,并进行重塑。如果两个输入都是1d,则可能不需要进行这些检查。无需说明这是不可能的,也无需给出不同于OPC要求的解决方案。建设性批评总是受欢迎的。我们都是这里的程序员,有些人已经学到了很多,有些人刚刚开始。帮助或不帮助改正错误,但绝对没有必要嘲笑他们。向上投票以抵消向下投票。也许迂腐,但并非错误。在找到一个好的解决方案的道路上,Ndarray不是一个不重要的方面。