我正在编写一个小脚本,将 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[:]
但是,当我尝试将字典写入矩阵单元格时,它也会被复制到之前填充的所有单元格中,这导致矩阵仅包含最后一组的数据集。
我尝试了不同的语法和方法,但问题仍然存在。
所以我愿意接受任何关于导致数据集这种奇怪传播的原因的建议。
问题来自于将数据集名称/值对加载到
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)