Python h5py-为什么我收到广播错误?

Python h5py - Why do I get a broadcast error?(Python h5py-为什么我收到广播错误?)

本文介绍了Python h5py-为什么我收到广播错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试读取一个.h5文件data.h5,它有两个数据集,即‘data’和‘METADATA’。‘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:UsersuserAnaconda3envspy38libsite-packagesh5py\_hldataset.py", line 707, in __setitem__
    for fspace in selection.broadcast(mshape):
  File "C:UsersuserAnaconda3envspy38libsite-packagesh5py\_hlselections.py", line 299, in broadcast
    raise TypeError("Can't broadcast %s -> %s" % (target_shape, self.mshape))
TypeError: Can't broadcast (4,) -> (157,)

有什么问题?

h5py

如@hpaulj所述,h5py将推荐答案数据集作为NumPy数组返回。一开始可能会让人感到困惑--h5py使用了Python的字典语法来引用HDF5对象(组和数据集),但它们不是字典!你的尝试是在正确的轨道上。您需要修改它以将hdf['metaData']中的数据作为NumPy数组而不是列表使用。

下面的示例应该可以工作。因为我没有起始文件(data.h5),所以我创建了一个文件来复制映像中的值。创建该文件的代码在末尾。

注1:如果不使用'°'表示度数,此示例会更简单。这增加了处理字符串数据的额外步骤。这就是我使用np.char.decode()打印dset['Variable name']dset['Unit']的原因。有关这一点的更多信息,请参见下面的内容。

注意2:使用硬编码字符串大小时要小心。('Variable name', 'S10')来自前面一个问题(字符串较短)的答案。下面的代码从hdf['metaData']数据集数据类型获取大小,然后在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'xc2xb0',其中预期度数单位为'°'。这个角色与h5py有一些复杂之处。它在Python和NumPy中都很好。但是,h5py(和hdf5)不支持NumPy的Unicode数据类型;您需要使用Numpy字节数组(‘S’dtype)。这就是为什么在用h5py保存之前,我使用np.char.encode()将数组arr编码为arr2。这就是打印上述dset['Variable name']dset['Unit']时需要np.char.decode()的原因--您必须将编码的字符串字节数据解码回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和字符串字节之间的编码/解码的参考:

  • Strings in HDF5 - Encodings
  • Conversion from U3 dtype to ascii
  • How to convert type from "str" to "numpy.string_" of each ndarray items?

这篇关于Python h5py-为什么我收到广播错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:Python h5py-为什么我收到广播错误?

基础教程推荐