使用迭代从numpy数组中删除元素

3
什么是从numpy数组中删除元素并检索它们的初始位置的最快方法?下面的代码没有返回应该返回的所有元素:
list = []
for pos,i in enumerate(ARRAY):
    if i < some_condition:
        list.append(pos)  #This is where the loop fails

for _ in list:
    ARRAY = np.delete(ARRAY, _)

它失败了,因为“p”应该是“pos”。 - John La Rooy
抱歉,之前有错别字,现已更正。 - KeVal
你为什么那么确定错误就在那一行代码? - user2357112
因为我自己检查了这些元素。 - KeVal
就此而言,“list”通常不是一个好的变量名称选择,因为您会遮蔽内置类型“list”。 :-) - mgilson
2个回答

5

你现在的做法似乎很低效。你应该使用更多内置的numpy功能,例如 np.where 或布尔索引。使用类似循环中的np.delete会使你从numpy中获得的性能优势全部消失...

举个例子(使用布尔索引):

keep = np.ones(ARRAY.shape, dtype=bool)
for pos, val in enumerate(ARRAY):
    if val < some_condition:
        keep[pos] = False
ARRAY = ARRAY[keep]

当然,这可能会更加简化(和概括):
ARRAY = ARRAY[ARRAY >= some_condition]

编辑

您在评论中提到需要相同的掩码用于操作其他数组,这不是问题。您可以保留掩码并将其用于其他数组:

mask = ARRAY >= some_condition
ARRAY = ARRAY[mask]
OTHER_ARRAY = OTHER_ARRAY[mask]
...

此外(也许这就是你的原始代码不起作用的原因),当你在循环中删除数组的第一个索引时,所有其他项都向左移动一个索引,因此你实际上没有删除最初标记的那些项目。
例如,假设你的原始数组是 [a, b, c, d, e],并且在初始遍历中,你标记了要删除的索引元素为[0, 2]ac)…… 在第一次执行删除循环时,你将删除索引0处的项——这将使你的数组变为:
[b, c, d, e]

现在,在第二次执行删除循环时,您将在新数组中删除索引2处的项

[b, c, e]

但是看起来,我们实际上删除了 d,而不是我们想要的删除 c!哎呀!

为了解决这个问题,你可能需要使用反向列表 reversed(list),但这仍然不能保证操作速度。


我曾考虑使用while循环,但它无法返回非法元素的位置。而我需要这些位置,因为其他一些数组也需要在这些特定位置移除元素(以便稍后可以绘制图形)。 - KeVal
@KeVal -- 这不是问题。只需掌握好掩码并将其用于其他数组即可(请参见我的编辑)。 - mgilson

2
您不需要迭代,尤其是在这种简单的条件下。而且您真的不需要使用delete
一个示例数组:
In [693]: x=np.arange(10)

掩码,布尔数组,其中条件为真(或假):

In [694]: msk = x%2==0
In [695]: msk
Out[695]: array([ True, False,  True, False,  True, False,  True, False,  True, False], dtype=bool)

where函数(或nonzero函数)将其转换为索引。

In [696]: ind=np.where(msk)
In [697]: ind
Out[697]: (array([0, 2, 4, 6, 8], dtype=int32),)

您可以在一次调用中使用整个ind来删除(无需迭代):
In [698]: np.delete(x,ind)
Out[698]: array([1, 3, 5, 7, 9])

您可以使用ind来保留这些值:
In [699]: x[ind]
Out[699]: array([0, 2, 4, 6, 8])

或者你可以直接使用布尔型变量msk

In [700]: x[msk]
Out[700]: array([0, 2, 4, 6, 8])

或者使用它的反义词:
In [701]: x[~msk]
Out[701]: array([1, 3, 5, 7, 9])

delete不仅仅是一种布尔掩码。这都是Python代码,所以你可以轻松地学习。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接