2017-08-08 3 views
0

Je dispose d'un fichier HDF5 qui contient une sorte de structure arborescente:Traversez le fichier/arbre HDF5 et continuez après le retour?

/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 

Ici /a_X/b_X sont des groupes et on peut supposer que le DataSet data contient une sorte de données numériques. Quelle est la meilleure façon d'extraire data? Bien sûr, je voudrais essayer:

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

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

mais cela arrête après autre chose que None est retourné pour la première fois. Bien sûr, on pourrait construire un objet global et l'ajouter mais je me demande s'il y a une sorte de «meilleure pratique» pour cela?

Répondre

1

Tout ce qui correspond à votre structure de script globale. Vous pourriez obtenir des indices dans le code de marche du fichier/répertoire.

Donc, avec un de mes fichiers de test, une simple fonction d'impression produirait:

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"> 

Je soupçonne que c'est l'un des usages les plus courants - juste une façon d'explorer rapidement la structure de données. Pour récupérer un dataset particulier, nous utilisons normalement un nom complet. Ou itérer sur plusieurs niveaux de clés.

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

Comme vous le soulignez, comme le démontre, si la fonction tente de renvoyer l'objet trouvé, il se ferme.

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]) 

Nous pourrions recueillir les éléments dans un dictionnaire (global ou appartenant à un objet):

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'] 

Mais le fichier lui-même peut être consulté comme un dictionnaire, donc cela pourrait ne pas ajouter grand-chose, sauf pour peut-être aplatir la nidification.

Ou comme une liste de valeurs ou une liste de tuples de nom et la valeur, etc.

Une classe simple:

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">] 
+0

Merci pour l'aide ici, je suppose que l'approche d'une classe logique dans mon cas - je vais vérifier;) – rammelmueller