如何从numpy数组中删除一些特定的元素?说我有

import numpy as np

a = np.array([1,2,3,4,5,6,7,8,9])

然后我想从a中删除3,4,7。我所知道的是这些值的下标(index=[2,3,6])。


当前回答

按值删除:

modified_array = np.delete(original_array, np.where(original_array == value_to_delete))

其他回答

如果没有想要删除的元素的索引,可以使用numpy提供的in1d函数。

如果一个一维数组的元素也存在于另一个数组中,则该函数返回True。要删除元素,只需对该函数返回的值求负即可。

注意,这个方法保持原始数组的顺序。

In [1]: import numpy as np

        a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
        rm = np.array([3, 4, 7])
        # np.in1d return true if the element of `a` is in `rm`
        idx = np.in1d(a, rm)
        idx

Out[1]: array([False, False,  True,  True, False, False,  True, False, False])

In [2]: # Since we want the opposite of what `in1d` gives us, 
        # you just have to negate the returned value
        a[~idx]

Out[2]: array([1, 2, 5, 6, 8, 9])

使用numpy.delete() -返回一个新数组,其子数组沿已删除的轴

numpy.delete(a, index)

关于你的具体问题:

import numpy as np

a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
index = [2, 3, 6]

new_a = np.delete(a, index)

print(new_a) #Prints `[1, 2, 5, 6, 8, 9]`

注意,numpy.delete()返回一个新数组,因为数组标量是不可变的,类似于Python中的字符串,所以每次对它进行更改时,都会创建一个新对象。也就是说,引用delete()文档:

"删除了由obj指定的元素的arr副本。请注意, 删除不会发生在原地……”

如果我发布的代码有输出,它是运行代码的结果。

Numpy数组是不可变的,这意味着从技术上讲不能从其中删除项。然而,你可以构造一个没有你不想要的值的新数组,就像这样:

b = np.delete(a, [2,3,6])

列表理解也是一种有趣的方法。

a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
index = np.array([2, 3, 6]) #index is changed to an array.  
out = [val for i, val in enumerate(a) if all(i != index)]
>>> [1, 2, 5, 6, 8, 9]

我不是一个麻木的人,我试了一下:

>>> import numpy as np
>>> import itertools
>>> 
>>> a = np.array([1,2,3,4,5,6,7,8,9])
>>> index=[2,3,6]
>>> a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))
>>> a
array([1, 2, 5, 6, 8, 9])

根据我的测试,这优于numpy.delete()。我不知道为什么会这样,也许是因为初始数组的大小较小?

python -m timeit -s "import numpy as np" -s "import itertools" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))"
100000 loops, best of 3: 12.9 usec per loop

python -m timeit -s "import numpy as np" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "np.delete(a, index)"
10000 loops, best of 3: 108 usec per loop

这是一个相当显著的差异(与我预期的方向相反),有人知道为什么会这样吗?

更奇怪的是,传递numpy.delete()一个列表的性能比遍历列表并给它单个索引的性能更差。

python -m timeit -s "import numpy as np" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "for i in index:" "    np.delete(a, i)"
10000 loops, best of 3: 33.8 usec per loop

编辑:这似乎与数组的大小有关。对于大型数组,numpy.delete()要快得多。

python -m timeit -s "import numpy as np" -s "import itertools" -s "a = np.array(list(range(10000)))" -s "index=[i for i in range(10000) if i % 2 == 0]" "a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))"
10 loops, best of 3: 200 msec per loop

python -m timeit -s "import numpy as np" -s "a = np.array(list(range(10000)))" -s "index=[i for i in range(10000) if i % 2 == 0]" "np.delete(a, index)"
1000 loops, best of 3: 1.68 msec per loop

显然,这一切都是相当无关紧要的,因为您应该始终保持清晰,避免重复工作,但我发现它有点有趣,所以我想我就把它留在这里。