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


212

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

import numpy as np

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

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

Answers:


285

使用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 副本请注意,删除不会就地发生 ...”

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


1
@IngviGautsson进行编辑时,您还将元素的正确值从2,3、6更改为3、4、7,如果现在运行代码,您将不会像原来那样获得正确的输出。 “正在回滚编辑
Levon

1
AttributeError:“列表”对象没有属性“删除”
munmunbb

3
@IngviGautsson不,您的评论有误导性。这按预期工作。但是,numpy.delete()的文档确实指出“通常最好使用布尔掩码”。举一个例子。
Biggsy

1
@Levon您可以添加2D示例吗?
MattS

7
@IngviGautsson你错了。它确实需要删除项目的索引,而不是项目本身。
Le Frite

64

有一个内置的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])

7
很高兴知道。我当时以为np.delete会慢一点,但是可惜,1000个整数的时间表示delete快了2倍。
wbg

1
这很棒,因为它可以对数组的值进行操作,而不必提供要删除的索引。例如:np.setdiff1d(np.array(['one','two']),np.array(['two', 'three']))
MD004

这也会对输出进行排序,这可能不是所需要的。否则非常好。
rayzinnz

问题是“我所知道的只是值的索引”。因此,这是根据其索引删除项目,而不是使用其值删除
Sherzod

35

Numpy数组是不可变的,从技术上讲,您不能从中删除任何项目。但是,您可以构造一个没有所需值的数组,如下所示:

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

1
+1表示“不变”。记住,numpy数组不利于快速更改大小(追加/删除元素)
eumiro 2012年

38
从技术上讲,numpy数组是可变的。例如,this:进行a[0]=1修改a。但是它们无法调整大小。
btel

3
定义说它是不可变的,但是如果通过赋予新值来让您修改它,那么它怎么不可变呢?
JSR

16

要按值删除:

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

问题是关于通过索引删除项目,而不是删除具有特定值的项目
Sherzod

5

我不是一个麻木的人,所以开枪:

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

显然,这完全无关紧要,因为您应该始终保持清晰并避免重新发明轮子,但是我发现它有点有趣,因此我想将其留在这里。


2
注意实际比较的地方!您有a = delte_stuff(a)第一次迭代,a每次迭代都会使它变小。使用inbuild函数时,不会将值存储回a,这会使a保持原始大小!除此之外,当您创建一个ouf index并检查是否删除某个项目时,可以大大加快您的功能。解决这两个问题,我得到了1万个项目:使用您的函数,每个循环6.22毫秒,对于numpy.delete,则为4.48毫秒,这大致就是您所期望的。
2013年

2
另外两个提示:取而代之的np.array(list(range(x)))使用np.arange(x),以及用于创建索引,你可以使用np.s_[::2]
迈克尔

1

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

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

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

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

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]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.