以小块创建非常大的NUMPY数组(PyTables与numpy.memmap)

时间:2014-10-06 10:52:49

标签: python numpy large-files mmap pytables

有很多关于SO的问题似乎是相同的,但他们并没有完全回答我的问题。我认为这对于计算科学家来说是一个非常常见的用例,因此我创建了一个新问题。

问题:

我从文件中读取了几个小的numpy数组(每个约10 MB)并对它们进行一些处理。我想创建一个更大的数组(~1 TB),其中数组中的每个维度都包含来自其中一个较小文件的数据。尝试在RAM中创建整个较大阵列(或其中很大一部分)的任何方法都不合适,因为它会使RAM泛滥并使机器停止运行。因此,我需要能够初始化较大的阵列并将其小批量填充,以便将每个批处理写入磁盘上的较大阵列。

我最初认为numpy.memmap是要走的路,但是当我发出像

这样的命令时
mmapData = np.memmap(mmapFile,mode='w+', shape=(large_no1,large_no2))
RAM泛滥,机器减速停止。

稍微调整一下后,似乎PyTables可能非常适合这类事情,但我并不确定。此外,很难在文档或其他地方找到一个简单的例子来说明这个常见的用例。

如果有人知道如何使用PyTables完成此操作,或者如果有更高效/更快的方法,请告诉我们!任何参考。示例赞赏!

2 个答案:

答案 0 :(得分:4)

这很奇怪。 np.memmap应该可以工作。我已经在12Gb RAM机器上使用250Gb数据而没有任何问题。

在创建memmap文件的那一刻,系统真的耗尽了内存吗?或者它沿着代码发生?如果它在文件创建时发生,我真的不知道问题会是什么。

当我开始使用memmap时,我犯了一些错误,导致我内存耗尽。对我来说,像下面的代码应该工作:

mmapData = np.memmap(mmapFile, mode='w+', shape = (smallarray_size,number_of_arrays), dtype ='float64')

for k in range(number_of_arrays):
  smallarray = np.fromfile(list_of_files[k]) # list_of_file is the list with the files name
  smallarray = do_something_with_array(smallarray)
  mmapData[:,k] = smallarray

它可能不是最有效的方式,但在我看来它的内存使用率最低。

Ps:请注意memmap(int)和fromfile(float)的默认dtype值是不同的!

答案 1 :(得分:0)

HDF5是一个可以有效存储大型磁盘阵列的C库。 PyTables和h5py都是HDF5之上的Python库。如果你使用表格数据,那么PyTables可能是首选;如果你只有普通数组,那么h5py可能更稳定/更简单。

有一些非核心的numpy阵列解决方案可以为您处理分块。 Dask.array会在您的分块文件集合之上为您提供简单的numpy语义(请参阅docs on stacking。)