通过迭代从 numpy 数组中删除元素

KeV*_*Val 3 python arrays iteration numpy

从 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, _)
Run Code Online (Sandbox Code Playgroud)

mgi*_*son 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]
Run Code Online (Sandbox Code Playgroud)

当然,这可能可以进一步简化(和概括):

ARRAY = ARRAY[ARRAY >= some_condition]
Run Code Online (Sandbox Code Playgroud)

编辑

您在评论中指出,您也需要相同的掩码来对其他数组进行操作——这不是问题。您可以保留掩码上的句柄并将其用于其他数组:

mask = ARRAY >= some_condition
ARRAY = ARRAY[mask]
OTHER_ARRAY = OTHER_ARRAY[mask]
...
Run Code Online (Sandbox Code Playgroud)

另外(也许这就是你的原始代码不起作用的原因),一旦你从循环中的数组中删除第一个索引,所有其他项目都会将一个索引向左移动,所以你实际上并没有删除您在初始阶段“标记”的相同项目。

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

[b, c, d, e]
Run Code Online (Sandbox Code Playgroud)

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

[b, c, e]
Run Code Online (Sandbox Code Playgroud)

但是看,我们并没有c像我们想要的那样删除,而是实际上删除了d!哦,快点!

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