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

时间:2016-01-21 03:28:44

标签: python arrays numpy iteration

在检索初始位置时从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, _)

2 个答案:

答案 0 :(得分:3)

你真的觉得这样做效率不高。您可能应该使用更多内置的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]
...

另外(也许这就是你的原始代码不工作的原因),只要你从循环中的数组中删除第一个索引,所有其他项都会将一个索引移到左边,所以您实际上并未删除与您标记的相同的商品&#34;在初始通行证上。

例如,假设您的原始数组为[a, b, c, d, e],并且在原始传递中,您在索引[0, 2]处标记了要删除的元素(ac) ...在第一次通过删除循环时,您将删除索引0处的项目 - 这将使您的数组成为:

[b, c, d, e]

现在在你的删除循环的第二次迭代中,你将删除新数组中索引2 的项目

[b, c, e]

但请注意,我们实际上删除了c,而不是像我们想要的那样删除d!哦,快点!

要解决这个问题,您可以在reversed(list)上编写循环,但这仍然不会导致快速操作。

答案 1 :(得分: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的一次调用中使用整个delete(无需迭代):

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代码,因此您可以轻松地学习它。