How to write HDF5 datasets to a np.array of dictionaries

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

我正在编写一个小脚本,将 HDF5 文件中的数据写入矩阵以供进一步分析。

文件结构如下: 该文件由几个组组成,这些组在下面的代码中使用 groupname_template 相应命名(例如“0, 0”,“0, 1”等)。每个组里面至少有一个数据集

我想创建一个字典矩阵,其中的每个元素都是一个由数据集名称和相应数据组成的字典。

这是我想出的代码:

import numpy as np
import h5py
import re

loaddir = r'C:\Users\User\Documents\data reading test\test_datafile.hdf5'
matrix_dict = np.full((10,10), {})
groupname_template = re.compile('\d+, \d+')

with h5py.File(loaddir, 'r') as loadedfile:
    for group in loadedfile.keys():
        if bool(re.match(groupname_template, group)):
            for key, value in loadedfile[group].items():
                matrix_dict[eval(group)[0], eval(group)[1]][key] = value[:]

但是,当我尝试将字典写入矩阵单元格时,它也会被复制到之前填充的所有单元格中,这导致矩阵仅包含最后一组的数据集。

我尝试了不同的语法和方法,但问题仍然存在。

所以我愿意接受任何关于导致数据集这种奇怪传播的原因的建议。

python-3.x numpy dictionary hdf5 h5py
1个回答
0
投票

问题来自于将数据集名称/值对加载到

matrix_dict
的方式。您必须创建 1 个字典来保存每个组的所有数据集名称/值对,然后将其分配给
(i,j)
中适当的
matrix_dict
索引。

我修改了您的代码以演示我认为您希望它如何工作。它用 我创建的一个简单的 HDF5 示例文件(每个有 4 个组/3 个数据集)。该文件的代码在最后。

下面我的例子的注释。

  • 我把
    matrix_dict
    的名字改成了
    arr_of_dict
    b/c 它是一个 NumPy 数组。我这样做是为了清楚 b/c 数组和矩阵是不同的对象类型。您正在创建一个数组。矩阵是用
    np.matrix()
    创建的专用二维“类数组”对象。 NumPy
    np.matrix()
    文档说:“不再推荐使用这个类”。
  • 我创建了
    arr_dict
    来加载每个数据集的名称/值对 组合成一个字典。它被分配到组
    (i,j)
    循环后的索引。
  • 我将
    group.items()
    生成的变量名称从
    key,value
    更改为
    ds_name, ds_obj
    以提高可读性(并强调它们是数据集名称和 H5 对象)。

检索组/数据集并加载到 np.array 字典中的代码:

with h5py.File(loaddir, 'r') as loadedfile:
    for group in loadedfile.keys():
        print(f'working on group: {group}')
        if bool(re.match(groupname_template, group)):
            print(f'reading datasets in group: {group}')
            arr_dict = {}
            for ds_name, ds_obj in loadedfile[group].items():
                arr_dict[ds_name] = ds_obj[:]
            arr_of_dict[eval(group)[0], eval(group)[1]] = arr_dict

打印上面创建的 np.array 中的值的代码:

for i in range(arr_of_dict.shape[0]):
    for j in range(arr_of_dict.shape[1]):
        arr = arr_of_dict[i,j]
        if len(arr):
            print(f'\ndatasets from group ({i}, {j})')
            [print(f'dataset {k}:\n{v}')  for k,v in arr.items() ]

创建示例文件的代码:

group_names = ['0, 0', '0, 1', '1, 0', '1, 1']
loaddir = 'test_datafile.hdf5'

with h5py.File(loaddir, 'w') as h5f:
    for group in group_names:
        grp = h5f.create_group(group)
        for i in range(3):
            arr = np.random.random(10).reshape(5,2)
            grp.create_dataset(f'ds_{i}', data=arr)
© www.soinside.com 2019 - 2024. All rights reserved.