在检索初始位置时从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, _)
答案 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]
处标记了要删除的元素(a
,c
) ...在第一次通过删除循环时,您将删除索引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代码,因此您可以轻松地学习它。