h5py 在通过类文件对象访问数据时执行许多小读取

h5py performs many small reads when accessing data over a file-like object

当我向 h5py 传递一个通过网络连接流式传输数据的 Python 类文件对象时,我有以下两个问题(类文件对象是有效的,例如不使用 smart_open).

对远程读取执行完整文件扫描

我能够通过将我的文件对象上的 read 函数设置为本地读取函数来计算读取调用,该函数使用 functools.partial 来计算调用和字节数。

我的数据是这样的:

print(h5file['table']) -> <HDF5 dataset "table": shape (1028, 7818600), type "<u2">

测试:

结论:

问题:

压缩和分块 I/O 是 HDF5/h5py 的功能。 (使用 chunked I/O 时会自动执行压缩)。首先检查数据集 chunksize 属性:print(h5file['table'].chunks)。这可能会确认您看到的 115k 值。块形状还应该指出为什么您将读取顺序视为列优先而不是行优先——因为块形状1 大于块形状[0].

如果块大小是导致问题的原因,您应该使用更大的块大小。但是,据我所知,您必须创建一个包含新数据集的新文件才能进行更改。

作为参考,这里有一个示例显示了一个简单的数组,其中定义了 3 个不同的块形状。文件关闭然后以读取模式重新打开。使用更大的块大小将数据读取和写入新文件。这解决了 group.copy() 的 h5py 限制(它在复制数据集时使用相同的块参数)。您还可以使用来自 HDF Group 的 'h5repack' 外部实用程序复制数据集并修改块 I/O 属性,参考:h5repack doc page.

import numpy as np
import h5py

size= 100
arr = np.random.random(size*size*size).reshape(size,size,size)

# Create file with small chunk size
with h5py.File('SO_69681364.h5_1','w') as h5file:
    h5file.create_dataset('chunked_a0',data=arr,chunks=(1,size,size))
    h5file.create_dataset('chunked_a1',data=arr,chunks=(size,1,size))
    h5file.create_dataset('chunked_a2',data=arr,chunks=(size,size,1))
    
    print(h5file['chunked_a0'].chunks)
    print(h5file['chunked_a1'].chunks)
    print(h5file['chunked_a2'].chunks)

# Open previous file and copy data to new file with larger chunk size
with h5py.File('SO_69681364_1.h5','r') as h5fr, \
      h5py.File('SO_69681364_2.h5','w') as h5fw:

    ds = h5fr['chunked_a0']
    h5fw.create_dataset('chunked_a0',data=ds,chunks=(10,size,size))
    h5fw.create_dataset('chunked_a1',data=ds,chunks=(size,10,size))
    h5fw.create_dataset('chunked_a2',data=ds,chunks=(size,size,10))
    
    print(h5fw['chunked_a0'].chunks)
    print(h5fw['chunked_a1'].chunks)
    print(h5fw['chunked_a2'].chunks)