【问题标题】:How is HDF5 different from a folder with files?HDF5 与包含文件的文件夹有何不同?
【发布时间】:2014-04-03 06:17:56
【问题描述】:

我正在处理将元数据添加到文件夹的open source project。提供的 (Python) API 允许您浏览和访问元数据,就像它只是另一个文件夹一样。因为它只是另一个文件夹。

\folder\.meta\folder\somedata.json

然后我遇到了HDF5 及其派生Alembic

阅读本书Python and HDF5 中有关 HDF5 的内容,我一直在寻找与使用文件夹中的文件相比使用它的好处,但我遇到的大部分内容都谈到了分层文件格式在其简单性方面的好处通过其 API 添加数据:

>>> import h5py
>>> f = h5py.File("weather.hdf5")
>>> f["/15/temperature"] = 21

或者它能够根据请求仅读取其中的某些部分(例如随机访问),以及并行执行单个 HDF5 文件(例如用于多处理)

你可以挂载 HDF5 文件,https://github.com/zjttoefs/hdfuse5

它甚至拥有一个强大而简单的基础概念,即 GroupsDatasets,来自 wiki 的内容如下:

  • 数据集,它们是同构类型的多维数组
  • 组,它们是容器结构,可以容纳数据集和 其他组

Dataset 替换为 File 并将 Group 替换为 Folder,整个功能集在我看来就像什么文件夹中的文件已经完全可以做到了。

对于我遇到的每一项好处,没有一个是 HDF5 独有的。

所以我的问题是,如果我要给你一个 HDF5 文件和一个包含文件的文件夹,两者都具有相同的内容,那么 HDF5 更适合哪种情况?

编辑:

已经收到一些关于 HDF5 可移植性的回复。

这听起来很不错,但我仍然没有得到一个例子,一个场景,HDF5 会胜过一个包含文件的文件夹。当一个文件夹在任何计算机、任何文件系统、网络上都可以读取、支持“并行 I/O”、在没有 HDF5 解释器的情况下可供人类读取时,为什么有人会考虑使用 HDF5。

我想说的是,包含文件的文件夹比任何 HDF5 都更便携。

编辑 2:

Thucydides411 只是举了一个可移植性很重要的场景示例。 https://stackoverflow.com/a/28512028/478949

我认为我从这个线程中的答案中得出的结论是,当您需要文件和文件夹的组织结构时,HDF5 非常适合,就像在上面的示例场景中一样,有很多(数百万)小(~ 1字节)数据结构;像单个数字或字符串。它通过提供有利于小而多而不是少数和大的“子文件系统”来弥补文件系统的不足。

在计算机图形学中,我们用它来存储几何模型和关于单个顶点的任意数据,这似乎与它在科学界的使用非常吻合。

【问题讨论】:

    标签: python persistence metadata hdf5


    【解决方案1】:

    作为一个开发了从使用文件文件夹到 HDF5 的科学项目的人,我想我可以对 HDF5 的优势有所了解。

    当我开始我的项目时,我在小型测试数据集上运行,并产生少量输出,在千字节的范围内。我从最简单的数据格式开始,表格编码为 ASCII。对于我处理的每个对象,我都在 ASCII 表上生成。

    我开始将我的代码应用于对象组,这意味着在每次运行结束时编写多个 ASCII 表,以及一个包含与整个组相关的输出的附加 ASCII 表。对于每个组,我现在都有一个如下所示的文件夹:

    + group
    |    |-- object 1
    |    |-- object 2
    |    |-- ...
    |    |-- object N
    |    |-- summary
    

    此时,我开始遇到第一个困难。 ASCII 文件的读写速度非常慢,并且它们不能非常有效地打包数字信息,因为每个数字都需要一个完整的字节来编码,而不是大约 3.3 位。所以我转而将每个对象编写为自定义二进制文件,这加快了 I/O 并减小了文件大小。

    当我扩大到处理大量(数万到数百万)组时,我突然发现自己要处理大量的文件和文件夹。对于许多文件系统来说,拥有太多小文件可能是一个问题(许多文件系统在它们可以存储的文件数量方面受到限制,无论有多少磁盘空间)。我还开始发现,当我尝试对整个数据集进行后处理时,读取许多小文件的磁盘 I/O 开始占用大量时间。我试图通过合并我的文件来解决这些问题,因此我只为每个组生成了两个文件:

    + group 1
    |    |-- objects
    |    |-- summary
    + group 2
    |    |-- objects
    |    |-- summary
    ...
    

    我还想压缩我的数据,所以我开始为组集合创建 .tar.gz 文件。

    此时,我的整个数据方案变得非常繁琐,如果我想将我的数据交给其他人,则需要花费大量精力向他们解释如何使用它。例如,包含对象的二进制文件有它们自己的内部结构,这种结构只存在于存储库中的 README 文件和我办公室的一张纸上。想要读取我的组合对象二进制文件之一的人必须知道标头中每个元数据条目的字节偏移量、类型和字节序,以及文件中每个对象的字节偏移量。如果他们不这样做,那么文件对他们来说就是乱码。

    我对数据进行分组和压缩的方式也带来了问题。假设我想找到一个对象。我必须找到它所在的 .tar.gz 文件,将存档的全部内容解压缩到一个临时文件夹,导航到我感兴趣的组,然后使用我自己的自定义 API 检索对象以读取我的二进制文件.完成后,我会删除临时解压缩的文件。这不是一个优雅的解决方案。

    此时,我决定切换到标准格式。 HDF5 之所以具有吸引力有很多原因。首先,我可以将我的数据整体组织成组、对象数据集和摘要数据集。其次,我可以放弃我的自定义二进制文件 I/O API,而只使用多维数组数据集将所有对象存储在一个组中。我什至可以创建更复杂数据类型的数组,例如 C 结构的数组,而不必仔细记录每个条目的字节偏移量。其次,HDF5 具有分块压缩,可以对数据的最终用户完全透明。因为压缩是分块的,如果我认为用户想要查看单个对象,我可以将每个对象压缩到一个单独的块中,这样只有用户感兴趣的数据集部分需要解压缩。分块压缩是一项非常强大的功能。

    最后,我现在可以只给某人一个文件,而不必解释它的内部组织方式。最终用户可以在命令行或 GUI HDFView 上以 Python、C、Fortran 或h5ls 读取文件,并查看其中的内容。这对于我的自定义二进制格式是不可能的,更不用说我的 .tar.gz 集合了。

    当然,您可以使用文件夹、ASCII 和自定义二进制文件复制您可以使用 HDF5 执行的所有操作。这就是我最初所做的,但它变成了一个令人头疼的问题,最终,HDF5 以一种高效且可移植的方式完成了我所做的一切。

    【讨论】:

    • 确实很有趣; +1
    • 只是好奇,如果你必须检索几乎所有的数据项,假设每隔几分钟一个 100k 大小的数组,以某种方式修改并写回,你认为 hdf5 是否合适,明智的阅读必须阅读所有内容,但 upsert 会说是最大数据集的 5%
    • 您认为偶尔出现 blob 的 SQLite 或 postgres 是否也是可行的替代方案,或者 HDF5 仍然更适合该问题?
    【解决方案2】:

    感谢您提出这个有趣的问题。带有文件的文件夹是否可移植,因为我可以将目录复制到 Mac 上的记忆棒上,然后在 PC 上查看相同的目录和文件?我同意文件目录结构是可移植的,这要感谢编写操作系统的人,但这与可移植文件中的数据无关。现在,如果这个目录中的文件是 pdf 的,它们是可移植的,因为有工具可以在多个操作系统中读取和理解 pdf(感谢 Adob​​e)。但是,如果这些文件是原始科学数据(ASCII 或二进制无关紧要),它们根本就不能移植。 ASCII 文件看起来像一堆字符,而二进制文件看起来像乱码。如果是 XML 或 json 文件,它们将是可读的,因为 json 是 ASCII,但它们包含的信息可能不可移植,因为 XML/json 标记的含义对于没有编写文件的人来说可能不清楚。这一点很重要,ASCII 文件中的字符是可移植的,但它们所代表的信息却不是。

    HDF5 数据是可移植的,就像 pdf 一样,因为许多操作系统中有工具可以读取 HDF5 文件中的数据(就像 pdf 阅读器,请参阅 http://www.hdfgroup.org/products/hdf5_tools/index.html)。还有许多语言的库可用于读取数据并以对用户有意义的方式呈现数据——这就是 Adob​​e Reader 所做的。 HDF5 社区中有数百个小组为他们的用户做同样的事情(请参阅http://www.hdfgroup.org/HDF5/users5.html)。

    这里也有一些关于压缩的讨论。在 HDF5 文件中压缩的重要一点是对象是独立压缩的,并且只有您需要的对象在输出时被解压缩。这显然比压缩整个文件并必须解压缩整个文件才能读取它更有效。

    另一个关键部分是 HDF5 文件是自描述的 - 因此,编写文件的人可以添加信息,帮助用户和工具了解文件中的内容。变量是什么,它们的类型是什么,是什么软件编写的,是什么仪器收集的,等等。听起来你正在使用的工具可以读取文件的元数据。 HDF5 文件中的属性可以附加到文件中的任何对象——它们不仅仅是文件级别的信息。这是巨大的。当然,这些属性可以使用以多种语言和多种操作系统编写的工具来读取。

    【讨论】:

      【解决方案3】:

      我目前正在评估 HDF5,所以有同样的问题。

      这篇文章——Moving Away from HDF5——提出了几乎相同的问题。这篇文章提出了一些好的观点,即只有一个 HDF5 库的实现,它是在现代开源标准相对不透明的情况下开发的。

      从标题可以看出,作者决定从 HDF5 转移到二进制文件的文件系统层次结构,其中包含 JSON 文件中的元数据数组。尽管在 HDF5 上进行了大量投资,但他们的手指因数据损坏和性能问题而被烧毁。

      【讨论】:

      • 感谢分享。
      【解决方案4】:

      我认为主要优势是便携性

      HDF5 存储有关数据集的信息,例如整数和浮点数的大小、类型和字节序,这意味着您可以移动 hdf5 文件并读取其内容,即使它是在具有不同架构的机器上创建的。

      您还可以将任意元数据附加到组和数据集。如果您的文件系统支持扩展属性,您也可以对文件和文件夹执行此操作。

      hdf5 文件是单个文件,有时它比压缩/tar 文件夹和文件更方便。这样做还有一个主要缺点:如果删除数据集,则无法在不创建新文件的情况下回收空间。

      通常,HDF5 非常适合存储大型数字数组,通常是科学数据集。

      【讨论】:

      • 在 HDF5 开发者的回应中,这也是他们的主要论点。但是我仍然看不到 HDF5 文件比任何包含一个或多个文件的文件夹更便携。例如纯文本、JSON、二进制;元数据可以很容易地存储在其中的任何一个中。
      • 纯文本(JSON、XML…)非常便携(除了编码问题),但二进制不是。例如,如果您在计算机上使用fwrite(C 语言)在文件中写入数字数组,将文件移动到具有不同架构的另一台计算机并尝试使用fread 读取它,它不会按预期工作。
      • 压缩一个 JSON,你就拥有了一个二进制文件。我没有看到容器如何在可移植性中发挥任何作用。
      • 假设您想在磁盘上存储一个 4 字节的整数。你需要一个 4 字节的文件,对吧?现在,如果您要将这个 4 字节的文件移动到另一台计算机并加载该数字,您最终可能会得到一个不同的数字。原因是字节的顺序可能不同。所以事实上,为了使您的(二进制)文件具有可移植性,它需要更多的位来存储有关字节顺序(元数据)的信息。 HDF5 为您做到这一点。
      • 我认为这与 innoSPG 关于 api 公开类似数据的通用接口的说法是一致的。独立存储 4 个字节,这是我应用 hdf5 之类的应用程序的常见用例,需要一致性。
      【解决方案5】:

      对我来说,我们只能在科学数据的相关上下文中将文件夹和文件与 HDF5 进行比较,其中最重要的数据是由一组元数据描述的数组。

      在一般情况下,当 Marcus 声称包含文件的文件夹比任何 HDF5 都更便携时,他是没问题的。我将补充一点,在一般情况下,带有文件的文件夹比 HDF5 文件更容易访问。明显的挑战是,使用“普通”文件夹和文件,不需要额外的 API 来访问数据。对于将数据和元数据保存在同一个文件中的 HDF5,这根本不可能。

      想象一下,要阅读您的 pdf 文件,您需要一个理解 HDF5 的新 pdf 阅读器吗?想象一下,要播放您的音乐,您需要一个可以解码 HDF5 的音乐播放器吗?要运行你的 python 脚本,python 解释器需要先解码 HDF5?或者总而言之,要启动您的 python 解释器,您的操作系统需要解码 HDF5?等等我根本无法写出这个答案,因为我的操作系统无法启动我的网络浏览器,也无法读取其内部文件,因为我之前 把所有东西都变成了 HD​​F5(也许我的硬盘中的所有东西都是一个大的 HDF5)。

      将元数据存储在单独的文件中具有巨大的优势,可以很好地处理已经存在的大量数据文件和软件,而不会带来任何额外的麻烦。

      我希望这会有所帮助。

      【讨论】:

      • 这有点像我的想法。但我仍在等待看到更适合 HDF5 的“科学数据”。 HDF5 看起来除了重新发明可以放在文件系统上的文件系统之外别无其他。文件系统是一项了不起的发明,却被低估了。直到有人将其放入文件中,人们才开始欣赏它的潜力。
      • 即使在科学数据的背景下,在我看来,HDF5 的主要相关性是 API 的可用性,除了可移植性之外,它还允许独立于语言使用数据。我每天在工作中使用 NetCDF。我喜欢这样一个事实,即我在 fortran 的几行代码中创建了一个包含元数据的数据文件,并从 python 轻松访问它,甚至让合作者从自己的程序轻松更新它而不会抱怨。但我还没有准备好将我的 fortran 代码或编译器放入 HDF5 文件中。在你为你的系统提供多语言 API 的那一天,我会转向它。
      • 这很有意义。用于元数据和普通旧数据类型存储的 api。文件和文件夹可能是可移植的,但它们不共享用于访问类似数据(例如数字)的通用界面。好点子,谢谢。
      【解决方案6】:

      需要将大量资源加载到内存中的游戏可能是 HDF5 可能比包含文件的文件夹更好的场景。从文件加载数据的成本包括寻道时间、打开每个文件所需的时间以及从文件中读取数据到内存中的时间。从 DVD 或蓝光读取数据时,这些操作可能会更慢。打开单个文件可以大大降低这些成本。

      【讨论】:

      • 感谢分享,这听起来很可能,但您运行过任何基准测试吗?我想 HDF5 也会因为能够随机访问其中的元素以及其他答案中提到的透明压缩/解压缩而对搜索产生影响。
      • 不幸的是,我还没有运行任何基准测试。您说得有道理,但我认为磁盘中的随机访问不太可能比内存中更快。
      • 好吧,它们都将从磁盘随机访问。例如,假设我们正在讨论一个 128gb 的数据集。如果数据在 HDF5 中,则在读取之前不会将其加载到内存中,而是按原样从磁盘中读取;就像它是文件和文件夹一样。
      【解决方案7】:

      是的,主要优点是 HDF5 是便携的。 HDF5 文件可以通过许多其他编程/解释语言访问,例如 Python(构建您的 API)、MATLAB、Fortran 和 C。正如 Simon 建议的那样,HDF5 在科学界被广泛用于存储大型数据集。根据我的经验,我发现仅检索某些数据集(和区域)的能力很有用。此外,为并行 I/O 构建 HDF5 库对于后期原始数据的后处理非常有利。

      由于文件也是自描述的,它不仅能够存储原始数据,还能够存储该数据的描述,例如数组大小、数组名称、单位和大量附加元数据。

      希望这会有所帮助。

      【讨论】:

      • 只访问 HDF5 的某些部分,而无需全部加载。这当然是一个很棒的功能,但不再是一个包含文件的文件夹。并行 I/O 归结为读取多个文件并“自我描述”以将文件夹中的元数据作为文件存储 - 例如 OSX 的 .DS_Store。
      【解决方案8】:

      HDF5 最终是一种存储数字的格式,针对大型数据集进行了优化。主要优势是支持压缩(在许多情况下可以更快地读取和写入数据)和快速的内核查询(检索满足某些条件的数据,例如温度超过 30 时的所有压力值) C)。

      您可以在同一个文件中组合多个数据集这一事实只是为了方便。例如,您可以有多个组对应于不同的气象站,每个组由多个数据表组成。对于每个组,您将有一组描述仪器详细信息的属性,每个表都有单独的设置。您可以为每个数据块拥有一个 h5 文件,在相应的位置具有一个属性,它会为您提供相同的功能。但是现在,您可以使用 HDF5 重新打包文件以优化查询,稍微压缩整个内容,并以惊人的速度检索您的信息。如果您有多个文件,每个文件都将单独压缩,并且操作系统将决定磁盘上的布局,这可能不是最佳选择。

      HDF5 允许您做的最后一件事是在内存中加载文件(或片段),并公开与磁盘中相同的 API。因此,例如,您可以根据数据大小和可用 RAM 使用一个或其他后端。在您的情况下,这相当于将相关信息复制到 Linux 中的 /dev/shm,您将负责将任何修改提交回磁盘。

      【讨论】:

      • 压缩,我不买。任何文件的压缩比 HDF5 存在的时间要长得多,我无法想象 HDF5 在这方面能提供更好的东西。如果是这样,它也可用于非 hdf5 文件。但是,“内核内查询”现在很有趣!我将不得不研究它,因为它类似于 - 如果我理解正确的话 - 数据库和 SQL 查询通常提供的内容。
      • 至于将 hdf5 文件或 if 块加载到内存中,并且仅针对该块使用公开的 api,我真的需要制作副本吗?我不能使用符号链接或硬链接吗?符号链接可能会在不同的配置中无限次地镜像同一组数据,如果某个配置比其他配置更频繁地被访问,符号链接也可能会持续存在。磁盘上文件的布局确实与操作系统无关。
      • 我应该指定“透明压缩”。数据被压缩,但您不必关心它。关于第二个,如果你想要 RAM 速度,你必须将它加载到 RAM 中;如果您希望数据在进程完成后保留,则必须将其写入磁盘。
      • 对于 Python,我非常喜欢 PyTables。一些内核搜索:pytables.github.io/usersguide/libref/…
      • 这是有道理的。谢谢你,我也会看看内核查询。
      【解决方案9】:

      要考虑的一个因素是磁盘访问的性能。使用 hd5f,所有内容都存储在磁盘的连续区域中,从而以更少的磁盘寻道和旋转更快地读取数据。另一方面,使用文件系统来组织数据可能涉及读取许多小文件,因此需要更多的磁盘访问。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-03
        • 1970-01-01
        • 1970-01-01
        • 2021-08-20
        • 2013-04-09
        • 2021-07-23
        • 1970-01-01
        相关资源
        最近更新 更多