我在 h5py 之间遇到了一些非常奇怪的交互, PyTables (通过 Pandas ),C++ 生成了 HDF5文件。看来,h5check和 h5py似乎可以处理包含“/”的类型名称,但 pandas/PyTables不能。显然,我的理解存在差距,所以:
我在这里有什么不明白的?
血淋淋的细节
我在 HDF5 文件中有以下数据:
[...]
DATASET "log" {
DATATYPE H5T_COMPOUND {
H5T_COMPOUND {
H5T_STD_U32LE "sec";
H5T_STD_U32LE "usec";
} "time";
H5T_IEEE_F32LE "CIF/align/aft_port_end/extend_pressure";
[...]
这是通过 C++ API 创建的。 h5check实用程序表示该文件有效。
请注意,CIF/align/aft_port_end/extend_pressure
不是指向组/节点/叶的路径。它是一个标签,我们在内部使用它恰好有一些包含“/”作为分隔符的内部结构。我们不希望 HDF5 文件知道任何相关信息:它不应该关心。显然,如果“/”在任何 HDF5 名称中都是非法的,那么我们必须将该分隔符更改为其他内容。
使用 PyTables(好的,Pandas 但它在内部使用 PyTables)读取文件,我得到一个
>>> import pandas as pd
>>> store = pd.HDFStore('data/XXX-20150423-071618.h5')
>>> store
/home/XXX/virt/env/develop/lib/python2.7/site-packages/tables/group. py:1156: UserWarning: problems loading leaf ``/log``::
the ``/`` character is not allowed in object names: 'XXX/align/aft_port_end/extend_pressure'
The leaf will become an ``UnImplemented`` node.
我在这个 question 中问过这个问题和 got told '/' 是 illegal in the specification .然而,h5py 的事情变得奇怪了。 ...
使用h5py读取文件,我得到了我想要的:
>>> f['/log'].dtype
>>> dtype([('time', [('sec', '<u4'), ('usec', '<u4')]), ('CI
F/align/aft_port_end/extend_pressure', '<f4')[...]
这或多或少是我的出发点。
不用说,我很困惑。我是否设法创建了一个非法的 HDF5以某种方式通过 h5check 的文件?是PyTables不支持这种边缘情况? ...我很困惑。
很明显,我可以像这样写一个简单的包装器:
>>> import matplotlib.pyplot as plt
>>> silly = pd.DataFrame(f['/log']['CIF/align/aft_port_end/extend_pressure'])
>>> silly.plot()
>>> plt.show()
从HDF5中获取所有数据归档到Pandas .但是,由于之前的混淆,我不确定这是否是一个好主意。我最大的担心是如果数据非常大,转换可能无法扩展...
最佳答案
我浏览了一下 h5check source而且我找不到任何地方来测试名称是否包含斜杠。您可以检查它可能产生的错误消息:
grep error_push h5checker.c -A1
您提供的链接明确指出对象名称中不允许使用斜杠。所以是的,我认为您创建了一个非法但通过 h5check 的文件。该工具似乎更侧重于二进制数据布局。我能找到的最接近的相关检查是防止重复名称。
在我看来,仅此而已。 h5py
和其他库能够以某种方式创建或读取此非法文件的事实无关紧要。规范说“不要在对象名称中放置斜杠”,所以您不需要。故事结束。
如果您不相信,可以这样想:如果您设法创建了一个文件名中带有斜杠的常规文件,会发生什么?大多数程序假定文件名不包含斜杠,因此它们能够通过在斜杠字符处分割目录路径来对其进行分区。您的文件会破坏这种行为,因此会引入许多微妙的(和不太微妙的)错误。用户会提示,程序员会讨厌你,系统管理员会诅咒你。
同样可以安全地假设,在 PyTables
旁边,许多其他库和程序将无法处理变量名中的斜线。 HDF 的好处在于它有很多工具,而使用斜杠则失去了这一优势。您可能认为这并不重要,也许您的 HDF-5 文件仅供内部使用。然而,情况可能会在 5 年内发生变化,因为情况往往如此。
硬着头皮把'/'换成'|'在将变量写入 HDF5 之前。阅读它们时将它们放回原处。您通过实现此方法损失的时间,通过避免 future 的错误和用户投诉,您将赢回 x 倍 (for x>1)。
抱歉我的咆哮,但我希望能说服你。
关于python - HDF5 文件名称中的 '/' 混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30070834/