遍历HDF5文件/树并在返回后继续?

时间:2017-08-08 07:40:39

标签: python numpy tree h5py

我有一个包含某种树结构的HDF5文件:

/a_1
/a_1/b_1
/a_1/b_1/data
/a_1
/a_1/b_2
/a_1/b_2/data
/a_2
/a_2/b_1
/a_2/b_1/data
/a_2
/a_2/b_2
/a_2/b_2/data

这里/a_X/b_X是组,可以假设DataSet data  包含某种数值数据。提取data的最佳方法是什么?当然,我会尝试:

def extract(name, node):
    if isinstance(node, hdf.Dataset):
        return node[...]
    return None

with h5py.File(some_file) as f:
    f.visititems(extract)

但是在第一次返回None之外的其他内容后停止。当然,人们可以建立一个全球性的对象并追加,但我想知道是否存在某种“最佳实践”。那个?

1 个答案:

答案 0 :(得分:3)

适合您的整体脚本结构。您可能会在文件/目录行走代码中获得提示。

因此,使用我的一个测试文件,一个简单的打印函数将产生:

def foo(name, obj):
   print(name, obj)
   return None

In [203]: f.visititems(foo)
Mcoo <HDF5 group "/Mcoo" (3 members)>
Mcoo/col <HDF5 dataset "col": shape (20,), type "<i4">
Mcoo/data <HDF5 dataset "data": shape (20,), type "<f8">
Mcoo/row <HDF5 dataset "row": shape (20,), type "<i4">
Mcsr <HDF5 group "/Mcsr" (3 members)>
Mcsr/data <HDF5 dataset "data": shape (20,), type "<f8">
Mcsr/indices <HDF5 dataset "indices": shape (20,), type "<i4">
Mcsr/indptr <HDF5 dataset "indptr": shape (11,), type "<i4">

我怀疑这是一种比较常见的用法 - 只是一种快速探索数据结构的方法。要获取特定的dataset,我们通常会使用完全限定的名称。或者迭代几个级别的键。

In [207]: f['Mcoo/row']
Out[207]: <HDF5 dataset "row": shape (20,), type "<i4">

正如您所记录的那样,如果该函数尝试返回找到的对象,它将退出。

def extract(name, node):
    if isinstance(node, h5py.Dataset):
        return node[...]
    return None
In [211]: x=f.visititems(extract)
In [212]: x
Out[212]: array([0, 6, 8, 9, 4, 6, 9, 0, 1, 8, 9, 1, 2, 4, 6, 5, 6, 0, 4, 6])

我们可以收集字典中的项目(全局或属于某个对象):

def extract(name, node):
    if isinstance(node, h5py.Dataset):
        dd[name] = node[...]
    return None

In [214]: dd = {}
In [215]: f.visititems(extract)
In [217]: list(dd.keys())
Out[217]: 
['Mcoo/col',
 'Mcsr/data',
 ...
 'Mcoo/row']

但是文件本身可以作为字典访问,所以这可能不会增加太多,除非可能会使嵌套变平。

或作为值列表,或名称和值的元组列表等

一个简单的课程:

class MyClass():
    def __init__(self):
        self.sets = []
    def __call__(self, name, node):
        if isinstance(node, h5py.Dataset):
            self.sets.append(node)
        return None

In [227]: M = MyClass()
In [228]: f.visititems(M)
In [229]: M.sets
Out[229]: 
[<HDF5 dataset "col": shape (20,), type "<i4">,
 <HDF5 dataset "data": shape (20,), type "<f8">,
 ... 
 <HDF5 dataset "indptr": shape (11,), type "<i4">]