上面的答案和cmets中提到了两个相似(但不同)的h5py I/O概念:
- HDF5 分块 用于启用分块 I/O 以提高性能。如果您在尝试读取内存不足的大型数据集时遇到 OOM 错误,则分块可能无济于事。
- NumPy 风格切片 用于从驱动器读取数据切片到内存(或将数据切片写入驱动器)。在读取非常大的文件时,切片是避免 OOM 错误的关键。
- 另外,当创建非常大的数据集时,通常需要使
它可调整大小。您可以分配一个初始大小,然后使用“.resize()”方法来增加磁盘上的大小。
我写了一个简单的例子来展示如何同时使用切片和分块。它一次将 100 张图像加载到可调整大小的数据集中。然后它会关闭文件并重新打开(只读)以一次将 100 张图像读取到 NumPy 数组中。
有效的分块需要适当的大小/形状,并且取决于您的阵列形状和 I/O 需求。我在示例中设置了块大小/形状以匹配我正在写入/读取的 100 个图像数组的大小。
这个例子应该让你开始。您需要修改以使用 5 维数组/数据集。
import numpy as np
import h5py
with h5py.File('SO_64645940.h5','w') as h5w:
img_ds = h5w.create_dataset('Images', shape=(100,480,640), dtype='f', maxshape=(None,480,640),chunks=(10,480,640))
next_img_row = 0
arr = np.random.random(100*480*640).reshape(100,480,640)
for cnt in range(1,10):
# print(cnt,img_ds.len(),next_img_row)
if img_ds.len() == next_img_row :
img_ds.resize(100*cnt,axis=0)
print('new ds size=',img_ds.len())
h5w['Images'][next_img_row:next_img_row+100] = arr
next_img_row += 100
with h5py.File('SO_64645940.h5','r') as h5r:
for cnt in range(10):
print('get slice#',str(cnt))
img_arr = h5r['Images'][cnt*100:(cnt+1)*100]