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

2025-02-25 09:07:00
admin
原创
27
摘要:问题描述:如何从 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])。解决方案 1:使用numpy.delete(),返回一个删除了...

问题描述:

如何从 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])。


解决方案 1:

使用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)
# Output: [1, 2, 5, 6, 8, 9]

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

“arr 的一个副本,其中 obj 指定的元素已被删除。请注意,删除不是就地发生的...”

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

解决方案 2:

使用np.setdiff1d

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

解决方案 3:

Numpy 数组是不可变的,这意味着从技术上讲您无法从中删除任何项目。但是,您可以构造一个不包含您不想要的值的新数组,如下所示:

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

解决方案 4:

按值删除:

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

解决方案 5:

如果我们知道要删除的元素的索引,则使用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:

由于我不是个 numpy 的人,所以我尝试了一下:

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

显然,这一切都是不相关的,因为你应该始终追求清晰度并避免重新发明轮子,但我发现它有点有趣,所以我想把它留在这里。

解决方案 7:

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

解决方案 8:

如果你不知道索引,你就不能使用logical_and

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

解决方案 9:

删除特定索引(我从矩阵中删除了 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]])

解决方案 10:

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

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]

解决方案 11:

如果您现在不知道索引,您可以执行以下操作:

arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
values = [3, 4, 7]
mask = np.isin(arr, values)
arr = np.delete(arr, mask)

此带有掩码的语法是在 1.19 版中引入的。

解决方案 12:

您还可以使用集合:

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]

解决方案 13:

过滤掉不需要的部分:

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

如果您有一个要删除的索引列表:

to_be_removed_inds = [2,3,6]
a = np.array([1,2,3,4,5,6,7,8,9])
a = a[[x for x in range(len(a)) if x not in to_be_removed]]
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1344  
  IPD(Integrated Product Development)流程是一套先进的产品开发管理体系,旨在通过整合跨部门资源,实现产品的高效开发与交付。在IPD流程中,确保项目按时交付是至关重要的,它直接关系到企业的市场竞争力和客户满意度。以下将从多个关键方面探讨如何在IPD流程阶段确保项目按时交付。精准的项目规划项...
IPD流程分为几个阶段   0  
  IPD(Integrated Product Development)流程是一套先进的产品开发管理体系,旨在缩短产品上市时间、提高产品质量、降低成本并增强企业的市场竞争力。深入理解IPD流程阶段的关键要素,对于企业成功实施IPD,实现产品开发的高效运作至关重要。IPD流程的概念与重要性IPD流程强调将产品开发视为一个整...
IPD测试流程   0  
  IPD(Integrated Product Development)产品开发流程是一套先进的、旨在提高产品开发效率与质量的管理体系。在这个体系中,评审环节起着至关重要的作用,它们如同关卡,确保产品在各个阶段都朝着正确的方向前进,符合市场需求和企业战略。其中有四个评审环节尤为关键,它们分别在不同阶段对产品进行全面审视,...
研发IPD流程   0  
  IPD(Integrated Product Development)研发管理体系是一套先进的、面向市场和客户的产品开发管理理念、模式和方法,旨在缩短产品上市时间、降低成本、提高产品质量,增强企业的核心竞争力。在IPD研发管理体系中,有五个关键流程起着至关重要的作用,它们相互关联、相互影响,共同构成了一个高效、协同的产...
IPD流程培训   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用