我觉得这很有趣,因为我现在正在处理类似的问题。
性能
为了更仔细地调查问题,我创建了以下文件
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文件中,因此稍后我可以从该点扩展模拟(我还可以更改一些参数,而无需从头开始)。此模拟的输出再次流入同一个文件。这很好-我只有一个文件用于一个模拟。但是,这种方法存在某些缺点:
- 当模拟崩溃时,您会得到一个不完整的文件-您无法从该文件开始新的模拟。
- 当另一个进程正在写入该文件时,没有简单的方法可以安全地查看hdf5文件。如果尝试从中读取并且另一个进程正在写入,则会得到已损坏的文件,所有数据都会丢失!
- 我不知道是否有任何简单的方法可以从文件中删除组(如果有人知道,请告诉我)。因此,如果需要重新构造文件,则需要从中创建新文件(
h5copy
,h5repack
,...)。
因此,我最终采用了这种方法,它效果更好:
- 我定期从模拟中刷新状态,然后写入新文件。如果模拟崩溃,则只需删除最后一个文件即可,我不会浪费太多cpu时间。
- 我目前仅绘制除最后一个文件之外的所有文件的数据。请注意,还有另一种方法:请参见这里,但我的方法肯定更简单,我对此满意。
- 处理多个小文件比一个巨大的文件要好得多-您可以看到进展等等。
希望这有所帮助。