【问题标题】:How can one efficiently remove a range of rows from a large numpy array?如何有效地从大型 numpy 数组中删除一系列行?
【发布时间】:2013-11-01 02:07:50
【问题描述】:

给定一个大型 2d numpy 数组,我想有效地删除一系列行,例如行 10000:10010。我必须在不同的范围内多次执行此操作,因此我也想使其可并行化。

使用numpy.delete() 之类的东西效率不高,因为它需要复制数组,占用太多时间和内存。理想情况下,我想做一些像创建视图这样的事情,但我不确定在这种情况下我该怎么做。屏蔽数组也不是一个选项,因为屏蔽数组不支持下游操作。

有什么想法吗?

【问题讨论】:

  • 下游操作有哪些?您可以尝试通过跟踪要删除的行来伪造删除...

标签: python numpy


【解决方案1】:

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

【讨论】:

  • 谢谢,我怀疑没有办法解决这个问题(但让我们看看是否有人提出了创造性的解决方案)。我不明白您为什么建议先屏蔽然后删除 - 这比仅删除更好吗?
  • 这部分是关于您的代码如何确定要删除的内容的猜测。正如您所指出的,重复删除行范围将是低效的(就内存和时间而言)。此外,我将“我必须以不同的范围多次执行此操作”解释为可能可并行化的部分。要并行执行此操作,您需要保持底层数组不变,并且只需翻转适当的“已删除”位。然后,当您确定要删除的所有行时,您可以在最后的非并行步骤中执行真正的“删除”操作。
【解决方案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 也无济于事。

【讨论】:

    【解决方案3】:

    相对于上述情况,我不知道这有多快,但假设您有一个列表 L 的行索引,其中包含您希望从数组 A 中保留的行的行索引(“行”是指第一个索引,对于高维数组)。所有其他行将被删除。我们让 A 保存结果。

    A = A[np.ix_(L)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-14
      • 2011-03-10
      • 2014-01-02
      • 1970-01-01
      • 2015-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多