【问题标题】:Memory management in numpy arrays,pythonnumpy数组中的内存管理,python
【发布时间】:2016-08-30 09:33:50
【问题描述】:

处理非常大 (>50Gb) 的文件时出现内存错误(问题:RAM 内存已满)。

我的解决方案是:我只想读取 500 kb 的数据并处理(然后从内存中删除它并继续读取下一个 500 kb)。还有其他更好的解决方案吗?或者如果这个解决方案看起来更好,如何使用 numpy 数组?

这只是代码的 1/4(仅供参考)

  import h5py
  import numpy as np
  import sys
  import time
  import os
  hdf5_file_name = r"test.h5"
  dataset_name = 'IMG_Data_2'

  file = h5py.File(hdf5_file_name,'r+')
  dataset = file[dataset_name]
  data = dataset.value
  dec_array = data.flatten() 
  ........

此时出现内存错误,因为它试图将所有数据放入内存。

【问题讨论】:

  • 哪一行引发了错误?为什么你需要打电话给flatten()
  • 我需要进一步对数据进行一些处理和操作。例如:我需要确定一个特定数字在哪里,然后获取下一个数字的索引,将其存储在一个数组中并实现一个计数器。

标签: python arrays numpy memory


【解决方案1】:

快速解答

更长的答案

一个关键问题是您有多少 RAM(10GB)以及您正在进行什么样的处理(需要查看数据集中的每个元素一次或需要一次查看整个数据集) .

如果它小于 10GB 并且需要查看一次,那么您的方法似乎是最体面的一种。这是处理大于主内存的数据集的标准方法。我要做的是将一个块的大小从 500kb 增加到更接近你所拥有的内存量 - 可能是物理 RAM 的一半,但无论如何,在 GB 范围内,但不足以导致交换到磁盘和干扰你的算法。一个很好的优化是一次在内存中保存两个块。一个是进程,另一个是从磁盘并行加载。之所以可行,是因为从磁盘加载内容相对昂贵,但它不需要太多 CPU 工作——CPU 基本上是在等待数据加载。由于 GIL,在 Python 中更难做,但 numpy 和朋友不应该受此影响,因为他们在数学运算期间释放 GIL。 threading 包可能在这里有用。

如果您的 RAM 较低并且需要一次查看整个数据集(可能在计算某些二次时间 ML 算法时,甚至在数据集中进行随机访问时),事情会变得更加复杂,您可能不会可以使用以前的方法。要么将你的算法升级到线性算法,要么你需要实现一些逻辑,以使 numpy 等算法直接处理磁盘上的数据,而不是将其保存在 RAM 中。

如果您有 >10GB 的 RAM,您可以让操作系统为您完成繁重的工作,并增加足够的交换大小以捕获所有数据集。这样,所有内容都加载到虚拟内存中,但只有一个子集加载到物理内存中,操作系统处理它们之间的转换,因此所有内容看起来都像一个巨大的 RAM 块。但是如何增加它是特定于操作系统的。

【讨论】:

  • 非常感谢。我有一个简短的了解。我的 RAM 是 8GB,我想遍历整个数据。我想知道我是否可以继续使用 python 或切换到其他语言?
【解决方案2】:

memmap 对象可以在任何接受 ndarray 的地方使用。给定一个 memmap fp,isinstance(fp, numpy.ndarray) 返回 True。

在 32 位系统上,内存映射文件不能大于 2GB。

当 memmap 导致文件被创建或扩展超出文件系统中的当前大小时,新部分的内容是未指定的。在具有 POSIX 文件系统语义的系统上,扩展部分将用零字节填充。

【讨论】:

    猜你喜欢
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    相关资源
    最近更新 更多