2013-10-11 18 views
12

Ich habe eine Struktur Array von Matlab erstellt und in v7.3 Format mat-Datei gespeichert:Wie liest man eine v7.3-Mat-Datei über h5py?

struArray = struct('name', {'one', 'two', 'three'}, 
        'id', {1,2,3}, 
        'data', {[1:10], [3:9], [0]}) 
save('test.mat', 'struArray', '-v7.3') 

Jetzt möchte ich diese Datei über Python lesen mit h5py:

data = h5py.File('test.mat') 
struArray = data['/struArray'] 

Ich habe keine Ahnung wie die Struktur-Daten nacheinander von struArray zu bekommen:

for index in range(<the size of struArray>): 
    elem = <the index th struct in struArray> 
    name = <the name of elem> 
    id = <the id of elem> 
    data = <the data of elem> 
+0

Haben Sie eine tatsächliche Lösung hierfür finden? – Pastafarian

+0

Ich hatte eine ähnliche Frage, mit einer Teillösung: http://StackOverflow.com/Questions/29852481/Reading-All-Variables-in-Amat-File-with-Python-H5py/29856030#29856030 – CodyF

Antwort

0

Matlab 7.3-Dateiformat nicht sehr einfach ist, mit h5py zu arbeiten. Es stützt sich auf HDF5 Referenz, vgl. h5py documentation on references.

>>> import h5py 
>>> f = h5py.File('test.mat') 
>>> list(f.keys()) 
['#refs#', 'struArray'] 
>>> struArray = f['struArray'] 
>>> struArray['name'][0, 0] # this is the HDF5 reference 
<HDF5 object reference> 
>>> f[struArray['name'][0, 0]].value # this is the actual data 
array([[111], 
     [110], 
     [101]], dtype=uint16) 

struArray(i).id zu lesen:

>>> f[struArray['id'][0, 0]][0, 0] 
1.0 
>>> f[struArray['id'][1, 0]][0, 0] 
2.0 
>>> f[struArray['id'][2, 0]][0, 0] 
3.0 

Beachten Sie, dass Matlab speichert eine Anzahl als ein Array von Größe (1, 1), damit die endgültige [0, 0] die Nummer zu bekommen.

struArray(i).data zu lesen:

>>> f[struArray['data'][0, 0]].value 
array([[ 1.], 
     [ 2.], 
     [ 3.], 
     [ 4.], 
     [ 5.], 
     [ 6.], 
     [ 7.], 
     [ 8.], 
     [ 9.], 
     [ 10.]]) 

struArray(i).name lesen zu können, ist es notwendig, das Array von ganzen Zahlen Zeichenfolge zu konvertieren:

>>> f[struArray['name'][0, 0]].value.tobytes()[::2].decode() 
'one' 
>>> f[struArray['name'][1, 0]].value.tobytes()[::2].decode() 
'two' 
>>> f[struArray['name'][2, 0]].value.tobytes()[::2].decode() 
'three' 
0

ich durch Anheizen der Dolmetscher und läuft help auf 01 beginnen würde. Es sollte Ihnen genug Informationen geben, um Sie zu beginnen. Andernfalls können Sie die Attribute eines beliebigen Python-Objekts mit dem Attribut print unter dem __dict__-Attribut ausgeben.

0

Es tut mir leid, aber ich denke, es wird ziemlich schwierig sein, Inhalte von Zellen/Strukturen von außerhalb Matlab zu bekommen. Wenn Sie die produzierten Dateien anzeigen (z. B. mit HDFView), werden Sie feststellen, dass es viele Querverweise gibt und keine offensichtliche Vorgehensweise.

Wenn Sie bei einfachen numerischen Arrays bleiben, funktioniert es gut. Wenn Sie kleine Zellenarrays mit numerischen Arrays haben, können Sie diese in separate Variablen konvertieren (z. B. Zelleninhalt1, Zelleninhalt2 usw.), die normalerweise nur einige Zeilen umfassen und direkt gespeichert und geladen werden können. Also in Ihrem Beispiel würde ich eine Datei mit Vars speichern name1, name2, name3, id1, id2, id3 ... usw.

EDIT: Sie h5py in der Frage angegeben, so ist das, was ich antwortete, aber erwähnenswert, dass mit scipy.io.loadmat sollten Sie in der Lage sein, die ursprünglichen Variablen zu erhalten umgewandelt numpy Äquivalente (zB Objekt-Arrays).

+4

Danke trotzdem ! Ich habe ein paar Tage mit diesem Problem zu kämpfen. Ich habe immer etwas wie und nicht den tatsächlichen Wert. Das 'scipy.io.loadmat' funktioniert jedoch nicht für das v7.3-Format der Matte-Datei. – Eastsun

-1

Es ist wirklich ein Problem mit Matlab 7.3 und h5py. Mein Trick besteht darin, den h5py._hl.dataset.Dataset Typ zu numpy Array zu konvertieren. Zum Beispiel

np.array(data['data']) 

Ihr Problem mit dem 'data' Feld lösen.

+0

Funktioniert nicht. Fügt einfach eine weitere Array-Ebene über die vorhandene hinzu. Z.B. 'array ([[, , ]], dtype = Objekt)' Und die vorhandenen Daten IS vom Typ 'h5py._hl.dataset.Dataset' – Pastafarian

2

visit oder visititems ist schnelle Möglichkeit, die Gesamtstruktur eines h5py Datei zu sehen:

fs['struArray'].visititems(lambda n,o:print(n, o)) 

Als ich dies durch Octave erzeugt auf einer Datei ausgeführt save -hdf5 ich:

type <HDF5 dataset "type": shape(), type "|S7"> 
value <HDF5 group "/struArray/value" (3 members)> 
value/data <HDF5 group "/struArray/value/data" (2 members)> 
value/data/type <HDF5 dataset "type": shape(), type "|S5"> 
value/data/value <HDF5 group "/struArray/value/data/value" (4 members)> 
value/data/value/_0 <HDF5 group "/struArray/value/data/value/_0" (2 members)> 
value/data/value/_0/type <HDF5 dataset "type": shape(), type "|S7"> 
value/data/value/_0/value <HDF5 dataset "value": shape (10, 1), type "<f8"> 
value/data/value/_1 <HDF5 group "/struArray/value/data/value/_1" (2 members)> 
... 
value/data/value/dims <HDF5 dataset "dims": shape (2,), type "<i4"> 
value/id <HDF5 group "/struArray/value/id" (2 members)> 
value/id/type <HDF5 dataset "type": shape(), type "|S5"> 
value/id/value <HDF5 group "/struArray/value/id/value" (4 members)> 
value/id/value/_0 <HDF5 group "/struArray/value/id/value/_0" (2 members)> 
... 
value/id/value/_2/value <HDF5 dataset "value": shape(), type "<f8"> 
value/id/value/dims <HDF5 dataset "dims": shape (2,), type "<i4"> 
value/name <HDF5 group "/struArray/value/name" (2 members)> 
... 
value/name/value/dims <HDF5 dataset "dims": shape (2,), type "<i4"> 

Dies kann nicht dasselbe, was MATLAB 7.3 produziert, aber es gibt eine Vorstellung von der Komplexität einer Struktur.

Ein verfeinerter Callback kann Werte anzeigen und der Ausgangspunkt für die Neuerstellung eines Python-Objekts (Wörterbuch, Listen usw.) sein.

def callback(name, obj): 
    if name.endswith('type'): 
     print('type:', obj.value) 
    elif name.endswith('value'): 
     if type(obj).__name__=='Dataset': 
      print(obj.value.T) # http://stackoverflow.com/questions/21624653 
    elif name.endswith('dims'): 
     print('dims:', obj.value) 
    else: 
     print('name:', name) 

fs.visititems(callback) 

produziert:

name: struArray 
type: b'struct' 
name: struArray/value/data 
type: b'cell' 
name: struArray/value/data/value/_0 
type: b'matrix' 
[[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]] 
name: struArray/value/data/value/_1 
type: b'matrix' 
[[ 3. 4. 5. 6. 7. 8. 9.]] 
name: struArray/value/data/value/_2 
type: b'scalar' 
0.0 
dims: [3 1] 
name: struArray/value/id 
type: b'cell' 
name: struArray/value/id/value/_0 
type: b'scalar' 
1.0 
... 
dims: [3 1] 
name: struArray/value/name 
type: b'cell' 
name: struArray/value/name/value/_0 
type: b'sq_string' 
[[111 110 101]] 
... 
dims: [3 1]