【问题标题】:Numpy slicing array memory consumptionNumpy 切片数组内存消耗
【发布时间】:2021-11-16 03:05:38
【问题描述】:

我有一个包含数十亿行和几百列的大型 2D numpy 数组,我想使用 x[:, [0, 1, 3, 5, 11, ...]] 选择大约 100 列我认为它只会创建原始 numpy 数组的视图,但实际上它正在沿流程创建数据副本并炸毁机器内存。为什么除了原始数据还需要消耗内存?有没有办法避免这样做?

【问题讨论】:

  • A view 是一个新数组,它使用原始的data-buffer(源数组的一维版本)和它自己的shapestridesbasic indexing 可以实现所有维度的切片。但是你有一个列的列表。它不能选择带有切片的不规则列模式。
  • 谢谢!这是否意味着如果我不使用列索引列表,而是使用范围,例如 x[:, 10:100],那么这里应该没有额外的内存消耗?
  • 我只是试了一下,看来我可以在不创建额外副本的情况下执行 [x:, 10:100] 和 [x:, 10:100:3] 之类的操作,因为因为它可以使用形状和步幅从原始数据中推断元素的位置,但是如果我执行 x[:, [1, 2, 3, 4, 5]],它将创建数据的副本

标签: python numpy numpy-ndarray


【解决方案1】:

正如上面所说的 cmets,基本索引只创建一个视图,因此避免了额外的内存。

如果您仍然需要使用列的索引列表来定义切片以便稍后访问子部分,那么我想您可以创建一个包装类来动态处理列切片:

import numpy as np

class Slicer:
    def __init__(self, data, column_indices):
        self._data = data
        self._columns = column_indices

    def __str__(self):    # used here only for debug/demonstration
        return self._data[:, self._columns].__str__()

    def __getitem__(self, indices):
        #print(rows)
        return self._data[indices[0], self._columns[indices[1]]]

a = np.random.rand(3, 6)
print(a)

b = Slicer(a, [1, 2, 4])
print(b)

c = b[:2, :]
print(c)
[[0.51290284 0.63379959 0.87076258 0.55393205 0.06055949 0.89285849]
 [0.8581135  0.05557465 0.22056647 0.95438171 0.0444966  0.16140554]
 [0.55770268 0.88788224 0.06126918 0.59973579 0.37484009 0.14142807]]
[[0.63379959 0.87076258 0.06055949]
 [0.05557465 0.22056647 0.0444966 ]
 [0.88788224 0.06126918 0.37484009]]
[[0.63379959 0.87076258 0.06055949]
 [0.05557465 0.22056647 0.0444966 ]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 2020-12-11
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多