Python 为什么我的大型HDF5数据集要花这么长时间才能建立索引?

Python 为什么我的大型HDF5数据集要花这么长时间才能建立索引?,python,hdf5,numpy-ndarray,Python,Hdf5,Numpy Ndarray,我有一个2D数据集,它存储在HDF5文件中,具有合理的分块。我访问它的方式如下: f = h5py.File("mydata.h5", "r") data = f.get("mydata") 其中data.shape~(1.e6,3000)和data.dtype='float32' 我想基于一维有效索引列表创建一个子集: valid_mask = np.load("valid.npy") # values 1 or 0, length ~ 1.e6, np.sum(valid_mask)

我有一个2D数据集,它存储在HDF5文件中,具有合理的分块。我访问它的方式如下:

f = h5py.File("mydata.h5", "r")
data  = f.get("mydata")
其中data.shape~(1.e6,3000)和data.dtype='float32'

我想基于一维有效索引列表创建一个子集:

valid_mask = np.load("valid.npy")  # values 1 or 0, length ~ 1.e6, np.sum(valid_mask) = 300000
valid_indices = np.where(valid_mask)
data_clean = data[valid_indices]
现在,如果我将有效_索引的长度限制在总列表的一小部分,那么上面的代码就可以工作;e、 例如,
valid\u index=np.where(valid\u mask[:maxlength]
。事实上,如果
maxlength=10000
,速度会非常快。但随着
maxlength
的增加,速度会变得非常慢。特别是
maxlength=100000
大约需要1分钟(约占总数据集的10%),但如果我仅将
maxlength
增加三倍,它将花费七倍的时间,并且在
maxlength
接近
len(有效掩码)
一整小时后它不会终止

我意识到,当HDF5文件被子集时,需要从磁盘上的HDF5文件中读取
数据
,但要对整个数据集执行此操作所需的时间远远超过按顺序读取原始12 GB文件所需的时间


我开始怀疑对循环使用蛮力
会比我在上面尝试的更快,但我不知道为什么。如果能深入了解为什么会陷入困境,我将不胜感激。

在运行该循环时,您是否查看了内存使用情况?一些numpy函数的内存开销非常高(
genfromtxt
例如,BitMe一次)您可能会遇到交换空间/页面文件,这会大大降低性能。根据我的Mac电脑上的系统监视器,当
imax
等于一百万时,它目前使用的内存大约为1GB。这不到我预期
data\u clean
所需内存的三分之一,并且远低于16GB的内存f内存。没有明显的内存压力。此外,进程的CPU运行在100%,因此这似乎是限制因素。但我也不知道为什么。@GrantPetty我不确定。我只是运行了一个快速测试,在所有其他条件相同的情况下,索引一个分块数据集肯定要慢一些。但我没有看到像您这样的低扩展性。索引您刚才尝试的是等效的,因此我并不奇怪您会看到相同的行为。如果您将整个数据集读取到内存中,然后使用NumPy索引创建子集,会发生什么情况?如:
data.value[valid\u index]
?另外,您使用的HDF5/h5py版本是什么?@bnaecker
data\u clean=data.value[valid\u mask==1,:]
只需3分钟就完成了工作。但这是可能的,因为我(几乎)有足够的RAM来容纳整个数据集。