从 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('< U3')” 其中 < 表示实际小于符号 我怎么解决这个问题。
【问题讨论】:
对于初学者来说,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 数据集的主要内容,如果未能解决你的问题,请参考以下文章