【问题标题】:Reducing RAM overloading when handling big matrices in python在 python 中处理大矩阵时减少 RAM 过载
【发布时间】:2014-08-21 23:34:37
【问题描述】:

我目前在一个使用 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 仍然会在某些时候溢出。

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

【问题讨论】:

  • 您可以随时序列化旧矩阵并将它们保存到文件中。这应该可以让您为当前计算释放一些 RAM,同时如果您愿意,仍然可以让您检查旧结果。 numpy 有一些功能可以让您非常轻松地将矩阵保存/加载到文件中。
  • 感谢您提供我们正在处理的建议,如果需要进行大型计算,可能会在 windows 上扩展交换

标签: python numpy scipy hdf5 pytables


【解决方案1】:

您可以通过使用pytables 进行压缩以HDF5 格式将图像存储到磁盘,从而大大降低您的RAM 需求。根据您的具体数据,与全内存方法相比,您可以获得显着的性能。

诀窍是使用 pytables 中包含的超快 blosc 压缩。

例如,此代码使用 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.

以下代码 sn-p 将两个数组加载回 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,您可以使用传统的切片符号逐块保存和读取它。您在磁盘上创建一个(分块的)pytables 数组,具有预设的大小和类型,然后以这种方式填充块:

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 文档:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-23
    • 2011-03-14
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多