h5py: 如何读取 hdf5 文件中的选定行?

4

如何在不加载整个文件的情况下从hdf5文件中读取给定行的数据集?我有一些非常大的hdf5文件,其中包含许多数据集。以下是我想要减少时间和内存使用的示例:

#! /usr/bin/env python

import numpy as np
import h5py

infile = 'field1.87.hdf5'
f = h5py.File(infile,'r')
group = f['Data']

mdisk = group['mdisk'].value

val = 2.*pow(10.,10.)
ind = np.where(mdisk>val)[0]

m = group['mcold'][ind]
print m

ind 不会给出连续的行,而是散乱的。

上面的代码失败了,但它遵循了切片一个 hdf5 数据集的标准方式。我收到的错误消息是:

Traceback (most recent call last):
  File "./read_rows.py", line 17, in <module>
    m = group['mcold'][ind]
  File "/cosma/local/Python/2.7.3/lib/python2.7/site-packages/h5py-2.3.1-py2.7-linux-x86_64.egg/h5py/_hl/dataset.py", line 425, in __getitem__
    selection = sel.select(self.shape, args, dsid=self.id)
  File "/cosma/local/Python/2.7.3/lib/python2.7/site-packages/h5py-2.3.1-py2.7-linux-x86_64.egg/h5py/_hl/selections.py", line 71, in select
    sel[arg]
  File "/cosma/local/Python/2.7.3/lib/python2.7/site-packages/h5py-2.3.1-py2.7-linux-x86_64.egg/h5py/_hl/selections.py", line 209, in __getitem__
    raise TypeError("PointSelection __getitem__ only works with bool arrays")
TypeError: PointSelection __getitem__ only works with bool arrays

在这里,仅仅说“失败了”却不展示错误信息或是具体哪里出错了是不被允许的。 - hpaulj
你正在将整个 mdisk 数组加载到内存中。我需要查阅文档才能确定有多少 mcold 被加载。这可能取决于 ind 是否为紧凑切片或分散在整个数组中的值。 - hpaulj
1个回答

5

我有一个包含以下信息的 h5py 文件样例:

data = f['data']
#  <HDF5 dataset "data": shape (3, 6), type "<i4">
# is arange(18).reshape(3,6)
ind=np.where(data[:]%2)[0]
# array([0, 0, 0, 1, 1, 1, 2, 2, 2], dtype=int32)
data[ind]  # getitem only works with boolean arrays error
data[ind.tolist()] # can't read data (Dataset: Read failed) error

这个错误是由于列表中有重复的值引起的。

但是使用具有唯一值的列表进行索引是可以正常工作的。

In [150]: data[[0,2]]
Out[150]: 
array([[ 0,  1,  2,  3,  4,  5],
       [12, 13, 14, 15, 16, 17]])

In [151]: data[:,[0,3,5]]
Out[151]: 
array([[ 0,  3,  5],
       [ 6,  9, 11],
       [12, 15, 17]])

正确维度的数组切片也是如此:

In [157]: data[ind[[0,3,6]],:]
Out[157]: 
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17]])
In [165]: f['data'][:2,np.array([0,3,5])]
Out[165]: 
array([[ 0,  3,  5],
       [ 6,  9, 11]])
In [166]: f['data'][[0,1],np.array([0,3,5])]  
# errror about only one indexing array allowed

如果索引正确 - 独特的值,并且匹配数组维度,那么它应该可以工作。

我的简单示例没有测试加载了多少数组。文档表明,元素是从文件中选择的,而不必将整个数组加载到内存中。


是的!谢谢。实际上这是一个匹配数组维度的问题。在上面的示例代码中,只需通过更改where语句即可:ind =(mdisk>val) - VGP
当然,如果您将h5文件转换为数组,则很容易选择行,但问题是:我们能否在不创建数组的情况下删除行?在我的情况下,这非常有用,因为我无法将整个数组加载到内存中。因此,我希望直接从h5文件中提取行。非常感谢。 - Tbertin
@Tbertin,我的 data 是数据集,而不是已加载的数组。因此,我展示了如何加载选定的行。切片索引也可以使用。 - hpaulj
即使数据是一个数据集,一旦你写了data[index],你就创建了一个数组,并将所选行加载到内存中。 - Tbertin
1
@Tbertin,你的“remove”和“extract”是指直接更改文件中的数据吗?如果是这样,你需要查看底层的HDF5代码,而不是Python接口。 - hpaulj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接