h5py hdf5将群组成员的属性提取到列表中

时间:2018-11-01 14:45:43

标签: python list attributes hdf5 h5py

问题: 我想将hdf5文件组的每个成员的属性提取到一个列表中(实际上并不完全如您所见,但这与问题无关,因此我将其保持简单)。

我认为访问功能是最有效的方法。我可以打印结果,但无法将结果附加到列表中。

这是“访问”所要调用的函数:

def func(name,obj):

   attribute = obj.attr.get('attribute_group')
   if attribute == 2:
       result = name
       print(result)

这是将函数func应用于组中所有成员的访问函数。

file = h5py.File(filepath,'r')
obj = file['/channel_groups/0/clusters/main/']
obj.visit(func)

到目前为止,一切都很好。但是,如何保存每次迭代中读出的结果?

无效的解决方案:

  1. 在函数的末尾添加return result使函数在返回第一个结果后停止-如文档中所述。

  2. 将附件添加到“访问”列表中会出现错误。

    results = [] obj.visit(results.append(func(obj,results)) TypeError: 'NoneType' object is not callable

  3. 将列表馈入函数并将其追加到函数中也无效:

    results = [] obj.visit(func(results)) TypeError: func() missing 1 required positional argument: 'obj'

或     obj.visit(func(obj,results)) TypeError: 'NoneType' object is not callable

不可能吗?我想避免在循环中调用每个成员,因为这会花费时间。

提前谢谢

1 个答案:

答案 0 :(得分:0)

How can I loop over HDF5 groups in Python removing rows according to a mask?

将列表附加到右边(还有[h5py] visit的其他示例)。

visit的参数必须是可调用的,即一个函数:

results = []
obj.visit(results.append(func(obj,results))
TypeError: 'NoneType' object is not callable

results.append(....)是一个完整的函数调用,python在调用visit之前执行。该列表追加的结果为None(该追加已就位)。如此有效,您只是在做

results=[]
results.append(func(obj, results))
obj.visit(None)

我认为您需要类似的东西

def func(name,obj):
   attribute = obj.attr.get('attribute_group')
   if attribute == 2:
       result = name
       print(result)
       results.append(result)
obj.visit(func)

请记住,您给visit提供的参数必须是未评估的函数,而不是某些函数调用的结果。它必须是callable


我创建了一个包含一组数据和两个数据集的文件

In [24]: results = []
In [25]: f.visit(results.append)
In [26]: results
Out[26]: ['agroup', 'agroup/bar', 'agroup/foo']

同时查看名称和所引用的对象:

In [27]: def func(name):
    ...:     print(name, f[name])
    ...:     
In [28]: f.visit(func)
agroup <HDF5 group "/agroup" (2 members)>
agroup/bar <HDF5 dataset "bar": shape (6,), type "<i8">
agroup/foo <HDF5 dataset "foo": shape (3,), type "<i8">

或更复杂的功能:

def func(name):
    obj = f[name]
    attr = list(obj.attrs.items())
    print(name, obj, attr)
    x = obj.attrs.get('x',None)
    if x:     # not none
        results.append((name, x))
In [35]: results=[]
In [36]: f.visit(func)
agroup <HDF5 group "/agroup" (2 members)> []
agroup/bar <HDF5 dataset "bar": shape (6,), type "<i8"> [('x', 10)]
agroup/foo <HDF5 dataset "foo": shape (3,), type "<i8"> [('x', 1)]
In [37]: results
Out[37]: [('agroup/bar', 10), ('agroup/foo', 1)]

再次查看Group文档,我发现有一个visititems方法:

def func(name, obj):
    attr = list(obj.attrs.items())
    print(name, obj, attr)
    x = obj.attrs.get('x',None)
    if x:     # not none
        results.append((name, x))

In [45]: results=[]
In [46]: f.visititems(func)
agroup <HDF5 group "/agroup" (2 members)> []
agroup/bar <HDF5 dataset "bar": shape (6,), type "<i8"> [('x', 10)]
agroup/foo <HDF5 dataset "foo": shape (3,), type "<i8"> [('x', 1)]
In [47]: results
Out[47]: [('agroup/bar', 10), ('agroup/foo', 1)]