【问题标题】:Concatenate large numpy arrays in RAM连接 RAM 中的大型 numpy 数组
【发布时间】:2015-09-25 01:59:05
【问题描述】:

我有一些 3D 图像数据,想用单通道堆栈构建一组 RGB 图像,即我尝试将三个形状为 (358, 1379, 1042) 的数组连接成一个形状为 (358, 1379, 1042, 3) 的数组。灵感来自skimage.color.gray2rgb 我试过了

np.concatenate((
    stack1[..., np.newaxis], 
    stack2[..., np.newaxis], 
    stack3[..., np.newaxis]), axis=-1)

然而,即使这些堆栈中的每一个只有大约 1GiB,这也会立即填满我空的 ~12GiB RAM ...所以我尝试预先分配一个最终形状的数组,然后用堆栈填充它,比如

rgb_stack = np.zeros(stack1.shape + (3,))
rgb_stack[:,:,:,0] = stack1

一旦我执行第二行,这也会耗尽我的 RAM。最后我尝试通过

stack1中的数据显式复制到rgb_stack
rgb_stack = np.zeros(stack1.shape + (3,))
rgb_stack[:,:,:,0] = stack1.copy()

结果相同。我做错了什么?

【问题讨论】:

  • 如果您不指定 dtype,zeros 将假定您需要 float64,而 (358, 1379, 1042, 3) float64 数组将占用 ~11.5 GiB。你的输入数组是什么 dtype?
  • 一些操作系统(尤其是 Linux)会很高兴地过度使用内存。当您创建零数组时,内核不会立即留出相应大小的 RAM 块 - 这仅在您实际尝试写入这些内存地址时发生,因此为什么您在尝试分配时只看到 MemoryErrorrgb_stack
  • 您是否将数据保存在其他地方?如果你这样做了,我会尝试在你将它放入 rgb_stack 后说 del stack1 来帮助 python 的垃圾收集器,在插入 stack2 后也是如此。
  • 在玩np.concatenate 时,我也使用np.zeros 作为默认stack3,对此感到抱歉......谢谢,祝你的论文好运! ;-)
  • 您可能还想研究其他可以处理分块数据的包,例如 PIMS、xray、bcolz、dask 等,以便您可以将整组数据作为一个数组进行操作,但是无需将其加载到连续的内存块中。

标签: python arrays numpy ram scikit-image


【解决方案1】:

总结从 cmets 中学到的问题; np.zeros 创建了一个 float64 数组,几乎 12GiB 大。这本身并不会因为 Linux 过度提交而填充 RAM,并且只会在数组被填充后将相应的 RAM 放在一边,在这种情况下,一旦它被图像数据填充。

因此将zeros 创建为另一个dtype 可以解决问题,例如

rgb_stack = np.zeros(stack1.shape + (3,), dtype=np.uint16)
rgb_stack[:,:,:,0] = stack1.copy()

uint16 堆栈一起工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-20
    • 2022-01-09
    • 2015-08-07
    • 2016-04-17
    • 2019-12-20
    • 2018-08-17
    • 2017-05-27
    • 2014-05-09
    相关资源
    最近更新 更多