HDF5 文件名称中的 '/' 混淆

'/' in names in HDF5 files confusion

我在 h5py, PyTables (via Pandas), and C++ generated HDF5 files. It seems that, h5check and h5py seem to cope with type names containing '/' but pandas/PyTables cannot 之间遇到了一些非常奇怪的交互。显然,我的理解有差距,所以:

这里有什么地方没看懂?


血淋淋的细节

我在 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 不是 表示通往 group/node/leaf 的路径。它是一个标签,我们在内部使用它恰好有一些包含“/”作为分隔符的内部结构。我们不希望 HDF5 文件知道任何相关信息:它不应该关心。显然,如果“/”在任何 HDF5 名称中都是非法的,那么我们必须将该分隔符更改为其他内容。

使用 PyTables(好的,Pandas but it uses 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. 

我在这个 and that '/' are illegal in the specification. However, things get stranger with h5py...

中问过这个问题

使用h5py读取文件,我得到了我想要的:

>>> f['/log'].dtype
>>> dtype([('time', [('sec', '<u4'), ('usec', '<u4')]), ('CI
F/align/aft_port_end/extend_pressure', '<f4')[...]

这或多或少是我的出发点。

不用说,我很困惑。我是否设法创建了一个以某种方式通过 h5check 的非法 HDF5 文件? PyTables 不支持这种边缘情况吗? ...我很困惑。


显然,我可以编写一个像这样的简单包装器:

>>> import matplotlib.pyplot as plt
>>> silly = pd.DataFrame(f['/log']['CIF/align/aft_port_end/extend_pressure'])
>>> silly.plot()
>>> plt.show()

HDF5 file into Pandas获取所有数据。但是,由于之前的混淆,我不确定这是否是一个好主意。我最大的担心是如果数据非常大,转换可能无法扩展...

你可以使用 h5py to read thru all your files and rewrite them without the offending characters, so that pytables 可以阅读它们吗?

如果它超出了规范,我假设您遇到的只是一些实现处理它而另一些不处理它...

确保您创建的是组,而不仅仅是正确的路径名 - 这可能是错误所在。如果您为对象创建组,然后使用叶名称命名对象 (extend_pressure 在上面)你不会有任何问题。

H5py 是 C HDF5 库的一个非常薄的包装器,pandas/pytables 在方法上更重 - 或者至少他们有更多自己的语义 - 所以他们正在检查确保您的对象名称中没有“/”。但请记住,每个人最终都在使用 HDF5 库,因为虽然 HDF5 很棒,但要进行替代实施将需要付出巨大的努力 - 超出 Pandas/Pytables.

的资源范围

次要免责声明:我之前破解过 HDF5 和 H5py 的内部结构。

我稍微浏览了一下 h5check source,但找不到任何地方可以测试名称是否包含斜线。您可以检查它可以产生的错误消息:

grep error_push h5checker.c -A1

您提供的链接明确指出对象名称中不允许使用斜杠。所以是的,我认为您创建了一个非法但通过 h5check 的文件。该工具似乎更侧重于二进制数据布局。我能找到的最接近的相关检查是防止重复名称。

我认为仅此而已。 h5py 和其他库以某种方式能够创建或读取此非法文件的事实无关紧要。规范说 "don't put slashes in object names",所以你没有。故事结束。

如果您不信服,可以这样想:如果您设法创建了一个文件名中带有斜杠的常规文件,会发生什么?大多数程序假定文件名不包含斜杠,因此它们能够通过在斜杠字符处分割目录路径来对其进行分区。您的文件会破坏这种行为,因此会引入许多微妙的(和不太微妙的)错误。用户会抱怨,程序员会讨厌你,系统管理员会诅咒你。

同样可以安全地假设,在 PyTables 旁边,许多其他库和程序将无法处理变量名中的斜杠。 HDF 的好处在于它有很多工具,而使用斜杠则失去了这一优势。您可能认为这并不重要,也许您的 HDF-5 文件仅供内部使用。然而,情况可能会在 5 年内发生变化,因为情况往往如此。

硬着头皮把'/'换成'|'在将变量写入 HDF5 之前。阅读它们时将它们放回原处。通过实施此方法而损失的时间,通过避免未来的错误和用户投诉,您将赢回 x 倍 (for x>1)

抱歉我的咆哮,但我希望能说服你。