如何高效地从大型numpy数组中删除一系列行?

8
给定一个大的2d numpy数组,我想高效地删除一系列行,比如说行 10000:10010。我需要多次这样做来处理不同的范围,所以我想让它可以并行化。
使用像 numpy.delete() 这样的方法并不高效,因为它需要复制数组,耗费太多时间和内存。理想情况下,我希望像创建一个视图那样做,但我不确定在这种情况下该怎么做。遮罩数组也不是一个选项,因为遮罩数组不支持下游操作。
有任何想法吗?

1
下游操作是什么?您可以通过跟踪将要删除的行来尝试伪造删除... - Jaime
3个回答

3

由于numpy数组定义了跨步数据结构,如果不使用掩码数组,您想要的将不可能实现。您最好的选择可能是使用掩码数组(或者您自己的布尔数组)来屏蔽删除的行,然后在向下传递之前对所有要删除的行进行单个真正的delete操作。


谢谢,我怀疑没有绕过这个问题的办法(但让我们看看是否有人能想出一个有创造力的解决方案)。不过,我不明白为什么你建议掩盖然后删除 - 怎样才比直接删除更好呢? - Bitwise
1
这部分是对你的代码如何工作进行猜测的一部分。正如你所指出的,重复删除行范围将是低效的(无论是在内存和时间方面)。我也把“我必须多次使用不同的范围”解释为可能可以并行化的部分。要在并行处理中实现这一点,您需要保持基础数组不变,只需切换适当的“已删除”位。然后,在确定所有要删除的行之后,您可以在最终的非并行步骤中执行真正的“删除”操作。 - Warren Weckesser

2

实际上,加速删除操作没有好的方法,正如您所提到的,这种删除需要在内存中复制数据。您可以像@WarrenWeckesser建议的那样,将多个删除操作组合在一起并一次性应用它们。以下是一个示例:

ranges = [(10, 20), (25, 30), (50, 100)]
mask = np.ones(len(array), dtype=bool)

# Update the mask with all the rows you want to delete
for start, end in ranges:
    mask[start:stop] = False

# Apply all the changes at once
new_array = array[mask]

并行化这个操作其实没有意义,因为你只是在内存中复制数据,所以这个过程本身就已经受限于内存速度了,增加CPU数量并不能帮助提升性能。


0

我不知道相对于上面的方法这个有多快,但是假设你有一个列表L,其中包含了你想要从数组A中保留的行的索引(通过“行”我指的是第一个索引,对于高维数组而言)。所有其他的行都将被删除。我们将让A保存结果。

A = A[np.ix_(L)]

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