从 Python 将字符串列表存储到 HDF5 数据集

Posted

技术标签:

【中文标题】从 Python 将字符串列表存储到 HDF5 数据集【英文标题】:Storing a list of strings to a HDF5 Dataset from Python 【发布时间】:2014-06-06 21:10:24 【问题描述】:

我正在尝试将可变长度的字符串列表存储到 HDF5 数据集。这个代码是

import h5py
h5File=h5py.File('xxx.h5','w')
strList=['asas','asas','asas']  
h5File.create_dataset('xxx',(len(strList),1),'S10',strList)
h5File.flush() 
h5File.Close()  

我收到一条错误消息,指出“TypeError:dtype 没有转换路径:dtype('&lt U3')” 其中 &lt 表示实际小于符号 我怎么解决这个问题。

【问题讨论】:

对于初学者来说,create_dataset 有一个错字。您能否给出您正在使用的确切代码,尤其是 strList 的来源? 抱歉打错了,我正在尝试将 pandas 数据帧序列化为 HDF5 文件,因此我必须创建一个包含所有列名称的标题,因此我提取了列表中的列名称并尝试将其写入 HDF5 数据集。 除了上面的拼写错误之外,代码模拟了完全相似的情况 您可能应该编辑您的问题并修正错字。 【参考方案1】:

来自https://docs.h5py.org/en/stable/special.html

在 HDF5 中,VL 格式的数据存储为任意长度的向量 基础类型。特别是,字符串以 C 风格存储在 空终止缓冲区。 NumPy 没有原生机制支持 这。不幸的是,这是代表的事实上的标准 HDF5 C API 和许多 HDF5 应用程序中的字符串。

谢天谢地,NumPy 有一个通用指针类型,形式为 “对象”(“O”)数据类型。在 h5py 中,可变长度的字符串被映射到 对象数组。附加到“O” dtype 的少量元数据 告诉 h5py 它的内容应该被转换为 VL 字符串 保存在文件中。

可以读取和写入现有的 VL 字符串,无需额外的 努力; Python 字符串和定长 NumPy 字符串可以是 自动转换为 VL 数据并存储。

例子

In [27]: dt = h5py.special_dtype(vlen=str)

In [28]: dset = h5File.create_dataset('vlen_str', (100,), dtype=dt)

In [29]: dset[0] = 'the change of water into water vapour'

In [30]: dset[0]
Out[30]: 'the change of water into water vapour'

【讨论】:

如果我有一个字符串列表['foo','bar'],如何将列表值分配给数据集? 次要更正:“HDF5 数据集中的字符串数据默认读取为字节:bytes 对象用于可变长度字符串,或 numpy 字节数组 ('S' dtypes) 用于固定-长度字符串。”(来源:docs.h5py.org/en/stable/strings.html#strings)所以第 30 行的输出实际上是 b'the change of water into water vapour'【参考方案2】:

我处于类似的情况,希望将数据框的列名存储为 hdf5 文件中的数据集。假设 df.columns 是我想要存储的,我发现了以下作品:

h5File = h5py.File('my_file.h5','w')
h5File['col_names'] = df.columns.values.astype('S')

这假定列名是可以用 ASCII 编码的“简单”字符串。

【讨论】:

【参考方案3】:

您正在读取 Unicode 字符串,但将数据类型指定为 ASCII。据the h5py wiki称,h5py目前不支持这种转换。

您需要以 h5py 句柄的格式对字符串进行编码:

asciiList = [n.encode("ascii", "ignore") for n in strList]
h5File.create_dataset('xxx', (len(asciiList),1),'S10', asciiList)

注意:并非所有用 UTF-8 编码的东西都可以用 ASCII 编码!

【讨论】:

从 hdf5 文件(在 python3 中)重新提取这些字符串的正确方法是什么? @DilithiumMatrix ASCII 也是有效的 UTF-8,但如果需要 str 类型,可以使用 ascii.decode('utf-8')。注意:我的回答会丢弃非 ASCII 字符。如果你用encode('unicode_escape') 保存它们,那么你需要decode('unicode_escape') 将它们转换回来。 @DilithiumMatrix。重新提取代码: stringlist=np.array(f['xxx']) vals=[str(el).strip('[]').strip('\'') for el in stringlist.astype( str)]

以上是关于从 Python 将字符串列表存储到 HDF5 数据集的主要内容,如果未能解决你的问题,请参考以下文章

在python中追加HDF5矩阵

在 hdf5 中存储可变长度字符串列表的标准方法是啥?

使用 Python 将 Blob 下载到本地存储

使用 h5py 将光栅图像添加到 HDF5 文件

使用 Pandas、Python 将数据附加到 HDF5 文件

如何将自定义类型的列表/数组写入 HDF5 文件?