python - 在 python 中处理大矩阵时减少 RAM 过载

标签 python numpy scipy hdf5 pytables

我目前所在的实验室使用 iPython Notebook 和 python 2.7 进行数据处理。我们处理285*384像素相机拍摄的图片,根据我们搜索观察的内容改变不同的参数。因此,我们需要处理大矩阵,随着数据处理的进展,矩阵分配的累积使得RAM/交换已满,因此我们无法再继续。

典型的初始数据矩阵的大小为100*285*384*16。然后我们必须分配许多其他矩阵来计算与该矩阵对应的时间平均值(大小为285 * 384 * 16,100是时间维度),然后我们需要线性拟合数据,所以我们有2 100 * 285 * 384 *16 个矩阵(线性拟合所需的 2 个估计参数),计算这些拟合的平均值和标准偏差......等等。因此,我们分配了很多大矩阵,这导致 RAM/交换空间满载。此外,我们还显示了与其中一些矩阵相关的一些图片。 当然,当我们进一步处理数据时,我们可以取消分配矩阵,但我们需要能够更改代码并查看旧计算的结果,而不必重建所有代码(计算有时相当长)。所有结果确实取决于之前的结果,因此我们需要将数据保存在内存中。

我想知道是否有某种方法可以扩展交换内存(例如在磁盘的“物理”内存上),或者通过更智能的编码方式以任何方式绕过我们的 RAM 限制。否则,我会使用我实验室研究所的一台具有 32 Go RAM 的服务器,但对于我们来说,无法使用我们自己的计算机来完成此操作,会浪费时间和符合人体工程学。崩溃发生在 Macintosh 和 Windows 中,由于 python 中 Windows 的 RAM 限制,我可能会在 Linux 上尝试,但我们计算机的 4Go RAM 在某些时候仍然会被填满。

我非常感谢您对这个问题的任何帮助,目前我在网上没有找到任何答案。预先感谢您的帮助。

最佳答案

您可以通过将图像存储到磁盘 HDF5 中来大幅减少 RAM 要求。使用 pytables 压缩进行格式化。根据您的具体数据,与全 RAM 方法相比,您可以获得显着的性能。

诀窍是使用速度极快的 blosc pytables 中包含压缩。

作为示例,此代码使用 blosc 压缩创建一个包含多个 numpy 数组的文件:

import tables
import numpy as np

img1 = np.arange(200*300*100)
img2 = np.arange(200*300*100)*10

h5file = tables.open_file("image_store.h5", mode = "w", title = "Example images",
                          filters=tables.Filters(complevel=5, complib='blosc'))

h5file.create_carray('/', 'image1', obj=img1, title = 'The image number 1')
h5file.create_carray('/', 'image2', obj=img2, title = 'The image number 2')

h5file.flush()  # This makes sure everything is flushed to disk
h5file.close()  # Closes the file, previous flush is redundant here.

以下代码片段将两个数组加载回 RAM:

h5file = tables.open_file("image_store.h5")  # By default it is a read-only open

img1 = h5file.root.image1[:]      # Load in RAM image1 by using "slicing"
img2 = h5file.root.image2.read()  # Load in RAM image1

最后,如果单个数组太大而无法放入 RAM,您可以使用传统的切片表示法逐 block 保存和读取它。您在磁盘上创建一个具有预设大小和类型的(分块的)pytables 数组,然后按以下方式填充 block :

h5file.create_carray('/', 'image_big', title = 'Big image',
                     atom=tables.Atom.from_dtype(np.dtype('uint16')),
                     shape=(200, 300, 400))

h5file.root.image_big[:100] = 1
h5file.root.image_big[100:200] = 2

h5file.flush()

请注意,这次您没有向 pytables 提供 numpy 数组(obj 关键字),而是创建了一个空数组,因此您需要指定形状和类型 (atom)。

有关更多信息,您可以查看官方 pytables 文档:

关于python - 在 python 中处理大矩阵时减少 RAM 过载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24509739/

相关文章:

python - 使用 numpy.genfromtxt 在 Python 3 中加载 UTF-8 文件

python - 将数组转换为序数回归编码的有效方法

python - Scipy:如何将 KD-Tree 距离从查询转换为千米(Python/Pandas)

python - 错误: cannot import name 'SpearmanRConstantInputWarning' from 'scipy.stats'

python - 当类的属性包含另一个类实例时如何指定 numba jitclass?

python - 如何从字典中获取随机值?

Python Ctypes 和线程

python - 找到 Pandas 数据框中两点之间平均边值最高的路径的有效方法?

python - matplotlib 中清晰易读的灰度线图?

python - 如何从 TfidfVectorizer 计算余弦相似度?