如何删除numpy数组中的特定元素

时间:2012-06-12 11:54:38

标签: python arrays numpy

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

import numpy as np

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

然后我要从3,4,7中删除a。我所知道的只是值的索引(index=[2,3,6])。

11 个答案:

答案 0 :(得分:219)

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

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()返回一个新数组,因为array scalars是不可变的,类似于Python中的字符串,因此每次对其进行更改时,都会创建一个新对象。即,引用delete() docs

  

“arr的副本,删除了obj指定的元素。注意   删除不会就地发生 ...“

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

答案 1 :(得分:39)

有一个numpy内置功能可以帮助解决这个问题。

import numpy as np
>>> a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = np.array([3,4,7])
>>> c = np.setdiff1d(a,b)
>>> c
array([1, 2, 5, 6, 8, 9])

答案 2 :(得分:31)

Numpy数组是immutable,这意味着您在技术上无法从中删除项目。但是,您可以构建一个 new 数组,而不包含您不想要的值,如下所示:

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

答案 3 :(得分:6)

不是一个笨拙的人,我开了一枪:

>>> 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

显然,这一切都非常无关紧要,因为你应该总是去清楚并避免重新发明轮子,但我发现它有点有趣,所以我想我会把它留在这里。

答案 4 :(得分:3)

要按值删除:

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

答案 5 :(得分:1)

如果我们知道要删除的元素的索引,则使用np.delete是最快的方法。但是,为了完整起见,让我添加另一种使用在np.isin的帮助下创建的布尔掩码来“删除”数组元素的方法。这种方法允许我们通过直接指定元素或通过其索引来删除元素:

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

按索引删除

indices_to_remove = [2, 3, 6]
a = a[~np.isin(np.arange(a.size), indices_to_remove)]

按元素删除(不要忘记重新创建原始的a,因为它是在前一行中重写的):

elements_to_remove = a[indices_to_remove]  # [3, 4, 7]
a = a[~np.isin(a, elements_to_remove)]

答案 6 :(得分:0)

如果您不知道索引,则无法使用logical_and

x = 10*np.random.randn(1,100)
low = 5
high = 27
x[0,np.logical_and(x[0,:]>low,x[0,:]<high)]

答案 7 :(得分:0)

删除特定索引(我从矩阵中删除了16和21)

import numpy as np
mat = np.arange(12,26)
a = [4,9]
del_map = np.delete(mat, a)
del_map.reshape(3,4)

输出:

array([[12, 13, 14, 15],
      [17, 18, 19, 20],
      [22, 23, 24, 25]])

答案 8 :(得分:0)

您还可以使用集合:

a = numpy.array([10, 20, 30, 40, 50, 60, 70, 80, 90])
the_index_list = [2, 3, 6]

the_big_set = set(numpy.arange(len(a)))
the_small_set = set(the_index_list)
the_delta_row_list = list(the_big_set - the_small_set)

a = a[the_delta_row_list]

答案 9 :(得分:0)

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

requirements = python3,kivy==2.0.0rc3, git+https://github.com/HeaTTheatR/KivyMD.git, sdl2_ttf==2.0.15

答案 10 :(得分:0)

如果没有要删除的元素的索引,则可以使用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])