h5py:如何将多个 HDF5 数据集堆叠到单个 np.array

问题描述 投票:0回答:1

我有一个 50GB h5 文件,其中仅包含数据集,并具有大约 7m x 256d numpy 数组 a 值。

我想生成它的一部分,因为整个文件无法加载到内存中,但我正在努力做到这一点。

所以,我有:

    f=h5py.File("./somefile.h5","r",libver='latest')
    keys_=list(f.keys()) # works - I get all the keys and check the length and it ads up.
    print(f[:5]) # fails saying it need a string for dataset name
    print(f[()][:5]) # fails same as above
    print(f['.'][:5]) #fails

这让我发疯!

重申一下,没有组,只有数据集 - 如何获取切片,例如 1m 切片?

hdf5 h5py
1个回答
0
投票

重新阅读您的问题后,我意识到您想要将数据集堆叠到单个数组中(例如,而不是对数据集进行切片)。我已经更新了我的答案以展示如何做到这一点。

首先,您不需要组来访问数据集。您只需在 H5 对象路径中指定数据集名称即可。

此外,您的代码不会调用

f.close()
。如果您在文件打开的情况下意外退出程序,这可能会导致问题。最好使用 Python 的文件上下文管理器 (
with/as:
)。这样,文件退出
with/as:
块时就会关闭。

如何将数据集堆叠为 np.array 切片:
此过程与原始答案类似。但是,它会在循环数据集之前创建一个足够大的空 NumPy 数组来保存数据。此过程假设所有数据集具有相同的形状(和数据类型)。由于我不知道您的数据集形状,因此我将其设为变量,数组的最后一个索引是数据集索引。此外,还进行了测试以确保每个数据集与目标数组的形状和数据类型相匹配。

堆叠数据集的代码如下:

with h5py.File("./somefile.h5","r") as f:
    ds_names = list(f.keys())
    n_slices = 5
    ds_shape = f[ds_names[0]].shape
    arr_shape =  ds_shape + (n_slices,)
    ds_arr = np.zeros(arr_shape,dtype=f[ds_names[0]].dtype)
    print(f'array; Type: {ds_arr.dtype}, Shape: {ds_arr.shape}')
    print(f'{ds_arr.shape[:-1]}')
    
    for cnt,ds in enumerate(ds_names[:n_slices]):
        if isinstance(f[ds], h5py.Dataset) and \
           f[ds].shape == ds_arr.shape[:-1] and and f[ds].dtype == ds_arr.dtype:
            print(f'For dataset {ds}; Type: {f[ds].dtype}, Shape: {f[ds].shape}')
            ds_arr[...,cnt] = f[ds][()]

切片数据集的原始答案
不,对于那些可能想要对数据集进行切片的人来说,切片语法与 NumPy 语法相同。因此,如果您有多个轴(维度),您将需要为每个维度指定切片大小。

下面的代码将访问您的文件,循环所有根级别对象(键),打印数据集信息,并尝试读取切片。这假设切片语法适合您的数据集。我添加了逻辑来测试每个对象都是一个数据集。

with h5py.File("./somefile.h5","r") as f:
    for ds in f:
        if isinstance(f[ds], h5py.Dataset):
            print(f'For dataset {ds}; Type: {f[ds].dtype}, Shape: {f[ds].shape}')
            print(f[ds][:5]) # gets a small slice assuming slice syntax is correct
© www.soinside.com 2019 - 2024. All rights reserved.