【问题标题】:h5py: How to index over multiple large HDF5 files without loading all their content into memoryh5py:如何在不将所有内容加载到内存的情况下索引多个大型 HDF5 文件
【发布时间】:2018-02-18 21:51:33
【问题描述】:

这是一个关于同时处理多个 HDF5 数据集同时尽可能将它们视为一个数据集的问题。

我有多个.h5 文件,每个文件都包含数万张图片。让我们调用文件

file01.h5
file02.h5
file03.h5

我现在想创建一个列表或数组,其中包含指向所有三个文件的所有图像的“指针”,而无需实际加载图像。

这是我目前所拥有的:

我先打开所有文件:

file01 = h5py.File('file01.h5', 'r')
file02 = h5py.File('file02.h5', 'r')
file03 = h5py.File('file03.h5', 'r')

并将他们的图像数据集添加到列表中:

images = []
images.append(file01['images'])
images.append(file02['images'])
images.append(file03['images'])

其中file01['images'] 是形状为 HDF5 的数据集,例如(52722, 3, 160, 320),即 52722 张图像。到目前为止一切顺利,尚未将任何内容加载到内存中。现在我想将这三个独立的图像列表合二为一,这样我就可以像处理一个大型数据集一样使用它。我试着这样做:

images = np.concatenate(images)

这就是它崩溃的地方。当我连接三个 HDF5 数据集时,它实际上将图像加载为 Numpy 数组,并且内存不足。

解决这个问题的最佳方法是什么?

我需要一个解决方案,让我可以像三个数据集一样对三个数据集进行 Numpy 切片和索引。

例如,假设每个数据集包含 50,000 张图像,并且我想加载每个数据集的第三张图像,我需要一个列表 images,它允许我将这些图像索引为

batch = images[[2, 50002, 100002]]

【问题讨论】:

  • 我认为不可能以您想要的方式连接“内存不足”的数据集。您可以做的是从单独文件中的 3 个较小的数据集创建一个大型数据集。然后查询内存不足的较大文件。这对您来说是一个可行的解决方案吗?
  • 非常感谢@jp_data_analysis!您可能是对的,但这是不可能的,但不幸的是,在单独的文件中创建一个大型数据集并不理想,因为它需要大量的磁盘空间开销(仍然需要单独的文件)。我想每次我想访问其中一个项目时,我只需要保持数据集分开并进行一堆丑陋的索引转换。
  • 是的,这可能是您唯一的选择。我的建议是创建一些基本函数来进行丑陋的索引转换。
  • @jp_data_analysis 我会这样做的,非常感谢您的帮助!
  • 类似的讨论没有被接受的答案:stackoverflow.com/questions/41572696/…;这是我已经回答的 [h5py] 问题列表。您可以搜索其他用户。

标签: python h5py


【解决方案1】:

HDF5 引入了“虚拟数据集 (VDS)”的概念。 但是,这不适用于 1.10 之前的版本。

我没有使用 VDS 功能的经验,但 h5py 文档更详细,h5py git 存储库有一个示例文件 here

'''A simple example of building a virtual dataset.
This makes four 'source' HDF5 files, each with a 1D dataset of 100 numbers.
Then it makes a single 4x100 virtual dataset in a separate file, exposing
the four sources as one dataset.
'''

import h5py
import numpy as np

# Create source files (1.h5 to 4.h5)
for n in range(1, 5):
    with h5py.File('{}.h5'.format(n), 'w') as f:
        d = f.create_dataset('data', (100,), 'i4')
        d[:] = np.arange(100) + n

# Assemble virtual dataset
layout = h5py.VirtualLayout(shape=(4, 100), dtype='i4')

for n in range(1, 5):
    filename = "{}.h5".format(n)
    vsource = h5py.VirtualSource(filename, 'data', shape=(100,))
    layout[n - 1] = vsource

# Add virtual dataset to output file
with h5py.File("VDS.h5", 'w', libver='latest') as f:
    f.create_virtual_dataset('data', layout, fillvalue=-5)
    print("Virtual dataset:")
    print(f['data'][:, :10])

更多详细信息可以在链接到pdfHDF group 上找到。图 1 很好地说明了这个想法。

【讨论】:

  • 从那以后我对此进行了更多研究。在 2.9 之前,h5py 中将不提供虚拟数据集。但是,可以使用 git master 分支上的版本来运行示例。
猜你喜欢
  • 2018-02-19
  • 2014-03-26
  • 1970-01-01
  • 2017-06-16
  • 1970-01-01
  • 1970-01-01
  • 2014-09-15
  • 2012-12-05
  • 1970-01-01
相关资源
最近更新 更多