在python中处理大型矩阵时减少RAM重载

时间:2014-07-01 11:58:43

标签: 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个内存,但是我们无法使用自己的计算机进行操作,这将耗费时间和人体工程学。在Macintosh和Windows中都发生了崩溃,由于python中Windows的RAM限制,我可能会尝试使用linux,但是我们计算机的4Go RAM仍然会在某些时候过满。

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

1 个答案:

答案 0 :(得分:2)

您可以使用HDF5压缩将图像以pytables格式存储到磁盘,从而大幅降低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.

并且以下代码片段将两个数组加载回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中,则可以使用传统的切片表示法来保存和读取它。您在磁盘上创建一个具有预设大小和类型的(chunked)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(obj关键字)提供一个numpy数组,但是你创建了一个空数组,因此你需要指定形状和类型(atom

有关详细信息,请查看官方的pytables文档: