2013-10-11 11 views
12

Mam tablicę struct utworzony przez Matlab i zapisany w pliku formatu v7.3 mat:Jak odczytać plik maty w wersji 7.3 przez h5py?

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

Teraz chcę odczytać ten plik za pośrednictwem Python stosując h5py:

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

nie mam pojęcia jak zdobyć jedną danych struct przez jednego z struArray:

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

Znalazłeś rzeczywiste rozwiązanie tego problemu? – Pastafarian

+0

Miałem podobne pytanie, z częściowym rozwiązaniem: http://stackoverflow.com/questions/29852481/reading-all-variables-in-a-mat-file-with-python-h5py/29856030#29856030 – CodyF

Odpowiedz

0

Matlab 7.3 Format pliku nie jest bardzo łatwe do pracy z h5py. Opiera się na referencji HDF5, por. Art. 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) 

Aby przeczytać struArray(i).id:

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

Zauważmy, że Matlab sklepów Szereg jako tablica rozmiarów (1, 1), stąd ostateczny [0, 0], aby uzyskać numer.

Aby przeczytać struArray(i).data:

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

Aby przeczytać struArray(i).name, konieczne jest, aby przekształcić tablicę liczb całkowitych na ciąg:

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

Chciałbym zacząć od rozpalania interpretera i działa help na struarray. Powinien dać ci wystarczająco dużo informacji, aby zacząć. W przeciwnym razie można zrzucić atrybuty dowolnego obiektu w języku Python za pomocą atrybutu .

0

Przykro mi, ale myślę, że będzie to dość trudne, aby uzyskać zawartość komórek/struktur z zewnątrz Matlaba. Jeśli obejrzysz wygenerowane pliki (np. Z HDFView) zobaczysz, że istnieje wiele odsyłaczy i nie ma oczywistych sposobów postępowania.

Jeśli trzymasz się prostych tablic numerycznych, działa dobrze. Jeśli masz małe macierze komórkowe zawierające tablice liczbowe, możesz je przekonwertować na oddzielne zmienne (np. Cellcontents1, cellcontents2 itd.), Co jest zwykle tylko kilkoma liniami i pozwala na ich bezpośrednie zapisywanie i ładowanie. Więc w przykładzie chciałbym zapisać plik z Vars name1, name2, name3, id1, id2, id3 ... itp

EDIT: Określono h5py w pytaniu tak to co odpowiedziałem, ale warto wspomnieć, że z scipy.io.loadmat powinieneś być w stanie uzyskać oryginalne zmienne zamieniane na NumPy odpowiedniki (np. tablice obiektów).

+4

Dzięki i tak ! Mam problem z tym problemem kilka dni. Zawsze miałem coś w stylu '' zamiast rzeczywistej wartości. Jednak plik 'scipy.io.loadmat' nie działa w przypadku pliku mat w wersji 7.3. – Eastsun

-1

To naprawdę problem z Matlabem 7.3 i h5py. Moją sztuczką jest zamiana typu h5py._hl.dataset.Dataset na numpy. Na przykład

np.array(data['data']) 

rozwiąże problemu z polem 'data'.

+0

Nie działa. Po prostu dodaje kolejną warstwę tablicową nad istniejącą. Na przykład. 'array ([[, , ]], dtype = obiekt)' A istniejące dane IS mają typ 'h5py._hl.dataset.Dataset' – Pastafarian

2

visit lub visititems jest szybki sposób widzenia ogólnej struktury h5py pliku:

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

Gdy uruchomię to na pliku wyprodukowanego przez Octave save -hdf5 uzyskać:

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

To może to nie to samo, co MATLAB 7.3, ale daje pojęcie o złożoności struktury.

Bardziej wyrafinowany oddzwanianie może wyświetlać wartości i może być punktem wyjścia do odtworzenia obiektu w języku Python (słownik, listy itp.).

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) 

produkuje:

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]