看看这个答案:How can I combine multiple .h5 file? - 方法 3b:将所有数据合并到 1 个可调整大小的数据集。它描述了一种将数据从多个 HDF5 文件复制到单个数据集中的方法。你想做类似的事情。唯一的区别是您的所有数据集都在 1 个 HDF5 文件中。
您没有说要如何堆叠 4D 数组。在我的第一个答案中,我将它们沿轴 = 3 堆叠。正如我在评论中所指出的,将合并的数据集创建为 5d 数组并沿第 5 轴(axis=4)堆叠数据更容易(也更简洁)。我喜欢这个有两个原因:代码更简单/更容易理解,2)axis=4 代表一个独特的数据集(而不是在 axis=3 上切片)更直观(对我来说)。
我写了一个独立的例子来演示这个过程。首先,它创建一些数据并关闭文件。然后它重新打开文件(只读)并为复制的数据集创建一个新文件。它遍历第一个文件中的组和数据集,并将数据复制到第二个文件中的合并数据集。首先是 5D 示例,然后是我的原始 4D 示例。
注意:这是一个简单的示例,适用于您的具体情况。如果你正在编写一个通用的解决方案,它应该在盲目合并数据之前检查一致的形状和数据类型(我不这样做)。
创建示例数据的代码(2 组,每组 5 个数据集):
import h5py
import numpy as np
# Create a simple H5 file with 2 groups and 5 datasets (shape=a0,a1,a2,a3)
with h5py.File('SO_69937402_2x5.h5','w') as h5f1:
a0,a1,a2,a3 = 100,20,20,10
grp1 = h5f1.create_group('group1')
for ds in range(1,6):
arr = np.random.random(a0*a1*a2*a3).reshape(a0,a1,a2,a3)
grp1.create_dataset(f'dset_{ds:02d}',data=arr)
grp2 = h5f1.create_group('group2')
for ds in range(1,6):
arr = np.random.random(a0*a1*a2*a3).reshape(a0,a1,a2,a3)
grp2.create_dataset(f'dset_{ds:02d}',data=arr)
合并数据的代码(2 组,每组 1 个 5D 数据集——我的偏好):
with h5py.File('SO_69937402_2x5.h5','r') as h5f1, \
h5py.File('SO_69937402_2x1_5d.h5','w') as h5f2:
# loop on groups in existing file (h5f1)
for grp in h5f1.keys():
# Create group in h5f2 if it doesn't exist
print('working on group:',grp)
h5f2.require_group(grp)
# Loop on datasets in group
ds_cnt = len(h5f1[grp].keys())
for i,ds in enumerate(h5f1[grp].keys()):
print('working on dataset:',ds)
if 'merged_ds' not in h5f2[grp].keys():
# If dataset doesn't exist in group, create it
# Set maxshape so dataset is resizable
ds_shape = h5f1[grp][ds].shape
merge_ds = h5f2[grp].create_dataset('merged_ds',dtype=h5f1[grp][ds].dtype,
shape=(ds_shape+(ds_cnt,)), maxshape=(ds_shape+(None,)) )
# Now add data to the merged dataset
merge_ds[:,:,:,:,i] = h5f1[grp][ds]
合并数据的代码(2 组,每组 1 个 4D 数据集):
with h5py.File('SO_69937402_2x5.h5','r') as h5f1, \
h5py.File('SO_69937402_2x1_4d.h5','w') as h5f2:
# loop on groups in existing file (h5f1)
for grp in h5f1.keys():
# Create group in h5f2 if it doesn't exist
print('working on group:',grp)
h5f2.require_group(grp)
# Loop on datasets in group
for ds in h5f1[grp].keys():
print('working on dataset:',ds)
if 'merged_ds' not in h5f2[grp].keys():
# if dataset doesn't exist in group, create it
# Set maxshape so dataset is resizable
ds_shape = h5f1[grp][ds].shape
merge_ds = h5f2[grp].create_dataset('merged_ds',data=h5f1[grp][ds],
maxshape=[ds_shape[0],ds_shape[1],ds_shape[2],None])
else:
# otherwise, resize the merged dataset to hold new values
ds1_shape = h5f1[grp][ds].shape
ds2_shape = merge_ds.shape
merge_ds.resize(ds1_shape[3]+ds2_shape[3],axis=3)
merge_ds[ :,:,:, ds2_shape[3]:ds2_shape[3]+ds1_shape[3] ] = h5f1[grp][ds]