有很多关于SO的问题似乎是相同的,但他们并没有完全回答我的问题。我认为这对于计算科学家来说是一个非常常见的用例,因此我创建了一个新问题。
问题:
我从文件中读取了几个小的numpy数组(每个约10 MB)并对它们进行一些处理。我想创建一个更大的数组(~1 TB),其中数组中的每个维度都包含来自其中一个较小文件的数据。尝试在RAM中创建整个较大阵列(或其中很大一部分)的任何方法都不合适,因为它会使RAM泛滥并使机器停止运行。因此,我需要能够初始化较大的阵列并将其小批量填充,以便将每个批处理写入磁盘上的较大阵列。
我最初认为numpy.memmap是要走的路,但是当我发出像
这样的命令时mmapData = np.memmap(mmapFile,mode='w+', shape=(large_no1,large_no2))
RAM泛滥,机器减速停止。
稍微调整一下后,似乎PyTables可能非常适合这类事情,但我并不确定。此外,很难在文档或其他地方找到一个简单的例子来说明这个常见的用例。
如果有人知道如何使用PyTables完成此操作,或者如果有更高效/更快的方法,请告诉我们!任何参考。示例赞赏!
答案 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。)