首页 > 解决方案 > 从 h5py 中的参考文件中提取文本

问题描述

我已经下载了一个 .h5 文件,其中包含各种对象(其中大部分是格式data.dat),包括一个名为.h5 的文件History.txt。访问它时,它显示<HDF5 dataset "History.txt": shape (), type "|O">. 我无法访问此对象内的文本。这里它说这type "|O"是一个参考文件。将其转换np.array为显示所有行和文本都被挤压在一起的输出。有没有办法提取/读取该对象中的文本?

代码如下:

data_0180 = h5py.File('file.h5', 'r+')
data_0180['OutermostExtraction.dir'].keys()

这个输出有很多键,我写了前几个:

<KeysViewHDF5 ['History.txt', 'Y_l2_m-1.dat', 'Y_l2_m-2.dat', 'Y_l2_m0.dat']>

这些 .dat 键包含数据,而这History.txt包含有关文件和该数据的某种信息。我想阅读该信息。当我尝试打印它时:

print(data_0180['OutermostExtraction.dir/History.txt'])

它显示以下输出:

<HDF5 dataset "History.txt": shape (), type "|O">

将其转换为 np.array 显示以下输出(我只提到了前几行,输出很大)

array('WaveformModes_4872 = scri.SpEC.read_from_h5("SimulationAnnex/Catalog/NonSpinningSurrogate/
BBH_CFMS_d18_q1_sA_0_0_0_sB_0_0_0/Lev4/rhOverM_Asymptotic_GeometricUnits.h5/Extrapolated_N2.dir", 
**{})\n# # WaveformBase.ensure_validity(WaveformModes_4872, alter=True, assertions=True)\n# WaveformModes.ensure_validity(WaveformModes_4872, alter=True,
assertions=True)\n# hostname = kingcrab\n# 
cwd = /mnt/raid-project/nr/woodford\n# datetime = 2017-01-16T19:24:54.304846\n# scri.__version__ = 2016.10.10.devc5096f2\n# spherical_functions.__version__ = 2016.08.30.dev77191149\n',
      dtype=object)

数组的形状为()。如何提取/读取此对象中的文本?

标签: pythonreferenceh5py

解决方案


正如我在评论中提到的,您有一个可变长度的字符串。NumPy 没有支持此数据类型的 dtype,因此 h5py 使用 object dtype 存储(以及一些元数据)。除了“有趣”之外,该数组是一个标量数组,因此您无法使用典型的 NumPy 索引访问元素。这就是.item()救援的地方。添加.decode()以完成该过程。您的代码应如下所示:

data_str = np.array(data_0180['OutermostExtraction.dir/History.txt']).item().decode('utf-8')

为了演示该行为(从头到尾),我从 h5py 文档中的可变长度字符串示例开始编写了一个示例。首先,它创建一个文件('foo.hdf5'),其中包含可变长度字符串数据的数据集——我使用了输出中的前 3 行。

写入后,文件将关闭并以只读模式重新打开。数据集被读入一个数组 ( arr),然后.item()用于访问元素并.decode('utf-8')对其进行解码(假设它被编码为'utf-8')。最后一行展示了如何将所有这些方法整合到一个 Python 语句中,该语句返回一个解码的字符串(变量data_str)。获得字符串后,您可以根据需要对其进行解析。

下面的例子:

import h5py
import numpy as np

vlstr = 'WaveformModes_4872 = scri.SpEC.read_from_h5("SimulationAnnex/Catalog/NonSpinningSurrogate/' + \
        'BBH_CFMS_d18_q1_sA_0_0_0_sB_0_0_0/Lev4/rhOverM_Asymptotic_GeometricUnits.h5/Extrapolated_N2.dir",' + \
        '**{})\n# # WaveformBase.ensure_validity(WaveformModes_4872, alter=True, assertions=True)\n# WaveformModes.ensure_validity(WaveformModes_4872, alter=True,'

dt = h5py.string_dtype(encoding='utf-8')

with h5py.File('foo.hdf5','w') as h5f:        
    ds = h5f.create_dataset('VLDS', dtype=dt, data=vlstr)   
          
with h5py.File('foo.hdf5','r') as h5f:            
    ds = h5f['VLDS']
    print('dtype=',ds.dtype)
    print('string dtype=',h5py.check_string_dtype(ds.dtype))
    
    arr = np.array(ds)
    print('\n',arr.item().decode('utf-8'))
    
    data_str = np.array(h5f['VLDS']).item().decode('utf-8')
    print('\n',data_str)

推荐阅读