h5py:切片阵列数据集的正确方法

Jia*_*Yow 11 python numpy h5py

我在这里有点困惑:

据我所知,h5py的.value方法读取整个数据集并将其转储到一个数组中,这个数组很慢而且不鼓励(通常应该替换为[()].正确的方法是使用numpy-esque切片.

但是,我得到了令人不快的结果(使用h5py 2.2.1):

import h5py
import numpy as np
>>> file = h5py.File("test.hdf5",'w')
# Just fill a test file with a numpy array test dataset
>>> file["test"] = np.arange(0,300000)

# This is TERRIBLY slow?!
>>> file["test"][range(0,300000)]
array([     0,      1,      2, ..., 299997, 299998, 299999])
# This is fast
>>> file["test"].value[range(0,300000)]
array([     0,      1,      2, ..., 299997, 299998, 299999])
# This is also fast
>>> file["test"].value[np.arange(0,300000)]
array([     0,      1,      2, ..., 299997, 299998, 299999])
# This crashes
>>> file["test"][np.arange(0,300000)]
Run Code Online (Sandbox Code Playgroud)

我想我的数据集非常小,.value不会显着影响性能,但第一种选择如何才能缓慢?这里的首选版本是什么?

谢谢!

更新 似乎我不够清楚,抱歉.我知道.value将整个数据集复制到内存中,而切片只检索适当的子部分.我想知道为什么在文件中切片比复制整个数组然后在内存中切片要慢.我一直认为hdf5/h5py是专门实现的,因此切片子部分总是最快的.

And*_*tte 21

要使用h5py进行快速切片,请坚持使用"普通香草"切片表示法:

file['test'][0:300000]
Run Code Online (Sandbox Code Playgroud)

或者,例如,阅读所有其他元素:

file['test'][0:300000:2]
Run Code Online (Sandbox Code Playgroud)

简单切片(切片对象和单个整数索引)应该非常快,因为它直接转换为HDF5 hyperslab选择.

该表达式file['test'][range(300000)]调用h5py的"花式索引"版本,即通过明确的索引列表进行索引.在HDF5中没有本地方法可以做到这一点,所以h5py在Python中实现了一个(较慢的)方法,当列表大于1000个元素时,遗憾的是它具有极差的性能.同样地file['test'][np.arange(300000)],以同样的方式解释.

也可以看看:

[1] http://docs.h5py.org/en/latest/high/dataset.html#fancy-indexing

[2] https://github.com/h5py/h5py/issues/293

  • 表达式 file['test'][range(300000)] 调用 h5py 版本的“花式索引”<-就是这样!鉴于它是一个范围,我没想到 h5py 会这样做,但它确实有意义。感谢您提供的链接,它们很有用。 (2认同)