用于处理HDF5文件中的大量大型2D阵列的建议(最佳实践)

时间:2015-11-04 11:34:44

标签: hdf5

我正在使用python程序将4000x4000数组写入hdf5文件。 然后,我通过c程序读取数据,我需要它作为输入来进行一些模拟。我需要大约1000个4000x4000阵列(意思是,我正在进行1000次模拟运行)。

我现在的问题如下:哪种方式更好",1000个单独的hdf5文件或一个带有1000个不同数据集的大hdf5文件(名为' dataset_%04d')?

非常感谢任何有关此类问题的建议或最佳做法行为(因为我对hdf5不太熟悉)。

如果有兴趣,这是我用来编写hdf5文件的python代码:

import h5py
h5f = h5py.File( 'data_0001.h5', 'w' )
h5f.create_dataset( 'dataset_1', data=myData )
h5f.close

2 个答案:

答案 0 :(得分:2)

这非常有趣,因为我目前正在处理类似的问题。

服务表现

为了更近距离地调查问题,我创建了以下文件

import h5py
import numpy as np

def one_file(shape=(4000, 4000), n=1000):
    h5f = h5py.File('data.h5', 'w')

    for i in xrange(n):
        dataset = np.random.random(shape)
        dataset_name = 'dataset_{:08d}'.format(i)
        h5f.create_dataset(dataset_name, data=dataset)
        print i

    h5f.close()


def more_files(shape=(4000, 4000), n=1000):

    for i in xrange(n):
        file_name = 'data_{:08d}'.format(i)
        h5f = h5py.File(file_name, 'w')
        dataset = np.random.random(shape)
        h5f.create_dataset('dataset', data=dataset)
        h5f.close()
        print i

然后,在IPython中,

>>> from testing import one_file, more_files
>>> %timeit one_file(n=25) # with n=25, the resulting file is 3.0GB
1 loops, best of 3: 42.5 s per loop
>>> %timeit more_files(n=25)
1 loops, best of 3: 41.7 s per loop

>>> %timeit one_file(n=250)
1 loops, best of 3: 7min 29s per loop
>>> %timeit more_files(n=250)
1 loops, best of 3: 8min 10s per loop

对我而言,差异非常令人惊讶,因为n=25拥有更多文件的速度更快,但对于更多数据集而言,这已不再是真理。

体验

正如其他人在评论中指出的那样,可能没有正确的答案,因为这是非常具体的问题。我处理hdf5文件用于我的等离子体物理研究。我不知道它是否对你有所帮助,但我可以分享我的hdf5体验。

我正在为用于转到一个hdf5文件的给定模拟运行大量模拟和输出。当模拟结束时,它将它的状态转储到这个hdf5文件,所以后来我能够采用这种状态并从那一点扩展模拟(我也可以改变一些参数,我不需要从头开始)。此模拟的输出再次转到同一文件。这很棒 - 我只有一个文件用于一次模拟。但是,这种方法存在某些缺点:

  1. 当模拟崩溃时,您最终会得到一个不完整的文件 - 您无法从该文件开始新的模拟。
  2. 没有简单的方法,当另一个进程写入该文件时,如何安全地查看hdf5文件。如果您尝试读取并且另一个进程正在写入,您最终会损坏文件并且所有数据都将丢失!
  3. 我不知道如何从文件中删除组的任何简单方法(我知道任何方式,请告诉我)。因此,如果我需要重新构建文件,我需要从中创建一个新文件(h5copyh5repack,...)。
  4. 所以我最终采用了这种方法,效果更好:

    1. 我定期从模拟中刷新状态,之后我正在写一个新文件。如果模拟崩溃,我只需要删除最后一个文件,我不会丢失那么多的CPU时间。
    2. 我目前只绘制所有文件中的数据,但最后一个。请注意,还有另一种方法:请参阅here,但我的方法肯定更简单,我对此感到满意。
    3. 处理比一个大文件更多的小文件要好得多 - 你会看到进度等等。
    4. 希望这有帮助。

答案 1 :(得分:0)

我知道,派对有点晚了,但我想我会分享我的经历。我的数据量较小,但从简单的分析角度来看,我实际上更喜欢一个大型(1000,4000,4000)数据集。在您的情况下,您似乎需要使用maxshape属性使其在您创建新结果时可扩展。保存多个单独的数据集使得很难查看数据集之间的趋势,因为您必须单独对它们进行切片。使用一个数据集,您可以做到,例如。 data[:, 5, 20]查看第3轴。另外,为了解决损坏问题,我强烈建议使用h5py.File作为上下文管理器:

with h5py.File('myfilename') as f:
    f.create_dataset('mydata', data=data, maxshape=(1000, 4000, 4000))

即使存在异常,也会自动关闭文件。我曾经因为数据损坏而不断诅咒,然后我就开始这样做了,从那时起就没有问题。