python - Python h5py - 为什么我会收到广播错误?
问题描述
我正在尝试读取一个 .h5 文件data.h5
,它有 2 个数据集,“数据”和“元数据”。'metaData' 包含一个 157x1 的字典,如下所示:
然后,我正在尝试编写一个新的 .h5 文件,其中包含 3 列:字典中每个变量的数字、名称(字典的第一列)和单位(字典的最后一列)。这是代码:
import numpy as np
import h5py as h5
hdf = h5.File('data.h5','r')
data1 = hdf.get('Data')
data2 = hdf.get('metaData')
dataset1 = np.array(data1)
dataset2 = np.array(data2)
#dictionary
hdfdic = dict(hdf['metaData'])
dic = hdfdic.get('dictionary')
dictionary = np.array(dic)
#write new h5 file
with h5.File('telemetry.h5', 'w') as var:
dt = np.dtype( [('n°', int), ('Variable name', 'S10'), ('Unit', 'S10')] )
dset = var.create_dataset( 'data', dtype=dt, shape = (len(dictionary),))
dset['n°'] = np.arange(len(dictionary))
dset['Variable name'] = [val[1] for val in dictionary[:][0][0]]
dset['Unit'] = [val[2] for val in dictionary[:][0][-1]]
data = dset[:]
print(data)
我得到错误:
Traceback (most recent call last):
File "c:/Users/user/Desktop/new/code.py", line 28, in <module>
dset['Variable name'] = [val[1] for val in dictionary[:][0][0]]
File "h5py\_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
File "h5py\_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
File "C:\Users\user\Anaconda3\envs\py38\lib\site-packages\h5py\_hl\dataset.py", line 707, in __setitem__
for fspace in selection.broadcast(mshape):
File "C:\Users\user\Anaconda3\envs\py38\lib\site-packages\h5py\_hl\selections.py", line 299, in broadcast
raise TypeError("Can't broadcast %s -> %s" % (target_shape, self.mshape))
TypeError: Can't broadcast (4,) -> (157,)
问题是什么?
解决方案
正如@hpaulj 所说,h5py 将 HDF5 数据集作为 NumPy 数组返回。一开始可能会让人感到困惑——h5py 使用 Python 的字典语法来引用 HDF5 对象(组和数据集),但它们不是字典!你的尝试是在正确的轨道上。您需要修改它以使用hdf['metaData']
NumPy 数组而不是列表中的数据。
下面的示例应该可以工作。由于我没有起始文件 ( data.h5
),因此我创建了一个文件来复制图像中的值。最后是创建该文件的代码。
注 1:如果这个例子不使用'°'
用于学位,这个例子会更简单。这增加了处理字符串数据的额外步骤。这就是我np.char.decode()
以前打印dset['Variable name']
和dset['Unit']
. 更多关于下面的内容。
注意 2:使用硬编码字符串大小时要小心。('Variable name', 'S10')
来自对较早问题的答案(字符串较短)。下面的代码从数据集 dtype 中获取大小hdf['metaData']
,然后在定义用于新数据集的 dtype 时使用它telemetry.h5
。
with h5.File('data.h5','r') as hdf:
#read dataset as a numpy array metaData, it is not a dictionary
metaData = hdf['metaData'][:]
print('dtype is:',metaData.dtype)
#write new h5 file
with h5.File('telemetry.h5', 'w') as var:
dt = np.dtype( [('n°', int), ('Variable name', metaData.dtype), ('Unit', metaData.dtype)] )
dset = var.create_dataset( 'data', dtype=dt, shape=(len(metaData),))
dset['n°'] = np.arange(metaData.shape[0])
dset['Variable name'] = metaData[:,0] # use first column of metaData
dset['Unit'] = metaData[:,-1] # use last column of metaData
for row in dset:
print(row[0], np.char.decode(row[1]), np.char.decode(row[2]))
这是我为模仿而编写的代码data.h5
。当您打印原始数据(作为字节字符串)时,您会看到学位单位的b'\xc2\xb0'
预期位置。'°'
使用 h5py 的那个字符有一些复杂性。在 Python 和 NumPy 中很好。但是,h5py(和 HDF5)不支持 NumPy 的 Unicode 数据类型;您需要使用 Numpy 字节数组('S' dtype)。这就是为什么我在使用 h5py 保存之前将np.char.encode()
数组编码arr
为的原因。arr2
这就是为什么np.char.decode()
在打印dset['Variable name']
及dset['Unit']
以上时是必要的——您必须将编码的字符串字节数据解码回 Unicode。
arr = np.array( \
[['ADC_ALT_TC', 'ADC_ALT_TC', 'ADC.ALT:TC [ft]', 'ft'],
['ADC_AOA_TC', 'ADC_AOA_TC', 'ADC.AOA:TC [°]', '°'],
['ADC_AOS_TC', 'ADC_AOS_TC', 'ADC.AOS:TC [°]', '°'],
['ADC_CAS_TC', 'ADC_CAS_TC', 'ADC.CAS:TC [kts]', 'kts'],
['ADC_OAT_TC', 'ADC_OAT_TC', 'ADC.OAT:TC [°]'., '°'],
['ADC_SpeedWarning_TC', 'ADC_SpeedWarning_TC','ADC_SpeedWarning:TC', ''],
['ADC_Stall_TC', 'ADC_Stall_TC','ADC_Stall:TC', ''],
['ADC_TAS_TC', 'ADC_TAS_TC', 'ADC.TAS:TC [kts]', 'kts'],
['AHRS1_accX_TC', 'AHRS1_accX_TC', 'AHRS1.accX:TC [m/s^2]', 'm/s^2'],
['AHRS1_accY_TC', 'AHRS1_accY_TC', 'AHRS1.accX:TC [m/s^2]', 'm/s^2'],
['AHRS1_accZ_TC', 'AHRS1_accZ_TC', 'AHRS1.accX:TC [m/s^2]', 'm/s^2'] ]
print(arr)
arr2 = np.char.encode(arr)
print(arr2)
with h5.File('data.h5','w') as hdf:
hdf.create_dataset('metaData',data=arr2)
以下是一些参考资料,供那些需要有关底层 HDF5/h5py 要求或 Unicode 和字符串字节之间的编码/解码的更多详细信息的人使用:
推荐阅读
- python - 对象上的 Python itertools 组合
- r - 有没有办法将图网络转换为 R 中的关系数据集?
- linux - 从 windows 机器到 linux 的 Ant 自动化
- bluetooth - 需要通过 BT 将联系人保存到手机
- ruby-on-rails - 仅在具有混合列类型的 ActiveRecord 对象中查找日期属性
- mysql - MySQL - chroot 环境中的 OUTFILE
- javascript - 如何从异步类函数 JavaScript 返回 Promise
- kubernetes - 无法按照虚拟机上 CentOS 7 上的官方安装指南安装 Kubernetes 最新版本
- django - “Currencysys”对象不可迭代
- c# - 为什么字母以路径的相反顺序出现(应该是)?