【问题标题】:'/' in names in HDF5 files confusionHDF5 文件中名称中的“/”混淆
【发布时间】:2015-07-16 05:47:41
【问题描述】:

我在h5pyPyTables(通过Pandas)和C++ 生成的HDF5 文件之间遇到了一些非常奇怪的交互。看来,h5checkh5py 似乎可以处理包含“/”的类型名称,但 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. 

我在questiongot 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')[...]

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

不用说,我很困惑。我是否设法创建了一个以某种方式通过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 文件中获取到Pandas。但是,由于之前的混淆,我不确定这是否是一个好主意。我最担心的是如果数据非常大,转换可能无法扩展......

【问题讨论】:

    标签: python pandas hdf5 pytables h5py


    【解决方案1】:

    您能否使用h5py 通读您的所有文件并在不包含违规字符的情况下重写它们,以便pytables 可以读取它们?

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

    【讨论】:

    • 这将是一次性修复,只要您可以更新坏字符源自的 c++ API。否则您将不得不将此预处理步骤放入您的工作流程中。
    • 第一部分是我上次编辑的内容:是的,我可以做到。不过,这似乎有点做作。后一部分,我不确定它是否超出规格。所有 h5check、C++ API 和 h5py 似乎都认为没问题。只有 PyTables 会抱怨。
    【解决方案2】:

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

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

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

    【讨论】:

    • "CIF/align/aft_port_end/extend_pressure" 不是组节点/叶的路径。它本身就是一个名称,只是一个HDF5不应该关心的具有内部结构的标签。至少,理论上是这样的。
    • @Sardathrion 是的,这就是我收集到的。不过可以把它想象成一个文件系统——文件名不能有路径斜杠(或者至少是不好的做法)。无论如何,虽然 HDF5 库与它一起工作 - 即使同一组制定规范,它也没有看到 100% 的规范 - 这只是现实。不幸的是,创建这样的数据集并不会自动创建路径以方便使用,但库就是这样 - 为了避免错误/问题正确使用组。
    【解决方案3】:

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

    grep error_push h5checker.c -A1
    

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

    在我看来,这就是它的全部。 h5py 和其他库以某种方式能够创建或读取这个非法文件的事实是无关紧要的。规范说“不要在对象名称中加上斜线”,所以你不要。故事结束。

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

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

    咬紧牙关,将“/”替换为“|”在将变量写入 HDF5 之前。当您阅读它们时将它们放回原处。通过实现这一点而损失的时间,您将通过避免未来的错误和用户投诉来赢回 x-fold (for x>1)

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

    【讨论】:

    • 投票、接受和赏金,因为这是最佳答案。
    • @Sardathrion,您的文件非常好。我知道复合类型成员的标签上没有与斜杠相关的限制。您链接的文档是指“组”命名空间中的名称;即文件中对象的 POSIX 样式路径。
    • @andrew-collette:那您认为这是 PyTables 中的错误吗? Sardathrion,尽管我显然误解了规范并且文件是正确的,但我坚持我的观点:使用斜杠可能会遇到其他库和程序出现问题的风险。更换它们可以很容易地避免这种情况。
    • 几乎可以肯定是 PyTables 中的一个错误。斜线替换作为一种解决方法很好。我不知道有任何其他环境有这种行为。
    • 如果我正在处理一个创建 hdf5 文件的程序并且我必须按原样使用它。但是,我知道该结构设置为没有“组”而只有“数据集”,类似于字典或键值对,其中键是包含正斜杠的字符串。有没有办法以这种方式读取 hdf5 而忽略斜线?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多