Czytaj pliki .mat w Pythonie

383

Czy w Pythonie można odczytać binarne pliki MATLAB .mat?

Widziałem, że SciPy rzekomo wspiera czytanie plików .mat, ale mi się nie udaje. Zainstalowałem SciPy w wersji 0.7.0 i nie mogę znaleźć loadmat()metody.

Gilad Naor
źródło

Odpowiedzi:

517

Wymagany jest import import scipy.io...

import scipy.io
mat = scipy.io.loadmat('file.mat')
Gilad Naor
źródło
6
Oficjalny samouczek SciPy.io: docs.scipy.org/doc/scipy/reference/tutorial/io.html
Franck Dernoncourt
18
scipy nie obsługuje plików mat w wersji 7.3 (patrz uwagi tutaj ). Zobacz odpowiedź vikrantt na rozwiązanie.
texnic
Można jednak zapisać pliki mat jako wcześniejsze wersje. patrz: mathworks.com/help/matlab/import_export/mat-file-versions.html (nagłówek: „Zapisz w niepoprawnej wersji pliku MAT”)
watsonic
5
np.save('myfile.mat','-v7')
watsonic
149

Ani scipy.io.savematnie scipy.io.loadmatdziała dla tablic MATLAB w wersji 7.3. Ale dobrą stroną jest to, że pliki MATLAB w wersji 7.3 są zestawami danych hdf5. Aby można je było odczytać za pomocą wielu narzędzi, w tym NumPy .

W przypadku Pythona potrzebujesz h5pyrozszerzenia, które wymaga HDF5 w twoim systemie.

import numpy as np
import h5py
f = h5py.File('somefile.mat','r')
data = f.get('data/variable1')
data = np.array(data) # For converting to a NumPy array
Vikrantt
źródło
6
Działa to dobrze, jeśli podczas zapisywania danych używasz flagi „-v7.3” w Matlab. Użycie domyślnej save(przynajmniej w Matlab R2014b) powoduje powstanie pliku, którego nie można odczytać przy użyciu powyższej techniki. Jeśli użyjesz flagi „-v7.3”, dane liczbowe można odczytać w porządku.
chipaudette
3
Tak, tak powiedziałem w moim poście. Musisz użyć -v7.3 podczas zapisywania w Matlabie. Powinieneś to zrobić i tak, ponieważ używa lepszego / bardziej obsługiwanego / znormalizowanego formatu.
vikrantt
4
Czy możesz wyjaśnić, jaki jest związek między f a danymi w twoim przykładzie? Jak przenieść f do tablicy numpy?
heracho
Zapisz zmienną za pomocą tego polecenia z wiersza poleceń:save('filename', '-v7.3', 'var1');
Kevin Katzke,
23

Najpierw zapisz plik .mat jako:

save('test.mat', '-v7')

Następnie w Pythonie użyj zwykłej loadmatfunkcji:

import scipy.io as sio
test = sio.loadmat('test.mat')
Bhanu Pratap Singh
źródło
15

Jest ładny pakiet o nazwie, mat4pyktóry można łatwo zainstalować za pomocą

pip install mat4py

Korzystanie z witryny jest proste:

Załaduj dane z pliku MAT

Funkcja loadmatładuje wszystkie zmienne przechowywane w pliku MAT do prostej struktury danych Pythona, używając tylko Pythona dicti listobiektów. Tablice numeryczne i komórkowe są konwertowane na zagnieżdżone listy uporządkowane w wierszach. Tablice są ściśnięte, aby wyeliminować tablice zawierające tylko jeden element. Wynikowa struktura danych składa się z prostych typów zgodnych z JSON formatem .

Przykład: Załaduj plik MAT do struktury danych Python:

from mat4py import loadmat

data = loadmat('datafile.mat')

Zmienna datazawiera dictzmienne i wartości zawarte w pliku MAT.

Zapisz strukturę danych Python w pliku MAT

Dane w języku Python można zapisać w pliku MAT za pomocą funkcji savemat. Dane muszą być skonstruowane w taki sam sposób jak w przypadku loadmat, czyli powinien być złożony z prostych typów danych, takich jak dict, list, str, int, ifloat .

Przykład: Zapisz strukturę danych Python w pliku MAT:

from mat4py import savemat

savemat('datafile.mat', data)

Parametr datapowinien być dictzmienny.

Cleb
źródło
Zauważ, że mat4py daje ci podobne do jsonów drzewo dykt, list, list list ... - w ogóle nie ma numpy. ( mat4py/cmd.py my.matpisze my.json, 1 długa linia.)
den
1
@denis: Tak, to również stwierdzono powyżej. Ale istotna uwaga: zazwyczaj podoba mi się ta struktura, np. W aplikacjach internetowych, ponieważ tablice numpy nie są serializowane przez JSON .
Cleb
mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files
Napotkano
@ s2t2: nigdy wcześniej nie napotkałem tego problemu. Jakiej wersji Matlaba i której wersji scipy używasz?
Cleb
ParseError: Nieoczekiwana długość nazwy pola: 43
Aleksejs Fomins
13

Po zainstalowaniu MATLAB 2014b lub nowszego można użyć silnika MATLAB dla Pythona :

import matlab.engine
eng = matlab.engine.start_matlab()
content = eng.load("example.mat", nargout=1)
Daniel
źródło
Wystąpił błąd: ModuleNotFoundError: Brak modułu o nazwie „pylab”.
Pada
3
Wystąpił błąd podczas wypróbowywania tych odpowiedzi? To dziwne, nie używa pylab.
Daniel
11

Czytanie pliku

import scipy.io
mat = scipy.io.loadmat(file_name)

Sprawdzanie typu zmiennej MAT

print(type(mat))
#OUTPUT - <class 'dict'>

Te klucze wewnątrz słownika są zmienne MATLAB , a wartościobiekty przypisane do tych zmiennych .

Daksh
źródło
7

Istnieje również silnik MATLAB dla Pythona opracowany przez MathWorks. Jeśli masz MATLAB, warto to rozważyć (sam tego nie próbowałem, ale ma o wiele więcej funkcji niż tylko czytanie plików MATLAB). Nie wiem jednak, czy wolno go rozpowszechniać innym użytkownikom (prawdopodobnie nie ma problemu, jeśli osoby te mają MATLAB. W przeciwnym razie może NumPy jest właściwą drogą?).

Ponadto, jeśli chcesz zrobić wszystkie podstawy sam, MathWorks zapewnia (jeśli link się zmieni, spróbuj googlematfile_format.pdf lub jego tytuł MAT-FILE Format) szczegółową dokumentację dotyczącą struktury formatu pliku. Nie jest to tak skomplikowane, jak osobiście myślałem, ale oczywiście nie jest to najłatwiejsza droga. Zależy to również od tego, ile funkcji .mat-plików chcesz obsługiwać.

Napisałem „mały” (około 700 wierszy) skrypt w języku Python, który potrafi odczytać podstawowe .matpliki. Nie jestem ani ekspertem w Pythonie, ani początkującym i napisanie go zajęło mi około dwóch dni (korzystając z dokumentacji MathWorks, do której odsyłam powyżej). Nauczyłem się wielu nowych rzeczy i było całkiem fajnie (przez większość czasu). Ponieważ napisałem skrypt Pythona w pracy, obawiam się, że nie mogę go opublikować ... Ale mogę tu udzielić porady:

  • Najpierw przeczytaj dokumentację.
  • Użyj edytora szesnastkowego (takiego jak HxD ) i wyszukaj plik referencyjny, .matktóry chcesz przeanalizować.
  • Spróbuj ustalić znaczenie każdego bajtu, zapisując bajty w pliku .txt i dodając adnotacje do każdej linii.
  • Użyj zajęcia zapisać każdy element danych (takich jak miCOMPRESSED, miMATRIX, mxDOUBLE, lub miINT32)
  • Struktura .matplików jest optymalna do zapisywania elementów danych w strukturze danych drzewa; każdy węzeł ma jedną klasę i podwęzły
mozzbozz
źródło
9
To jakaś szalona dokumentacja dostarczona przez matematyki. 40 stron wyjaśniających format, nie wspominając o tym, że jest to podzbiór HDF5.
Daniel
-1
from os.path import dirname, join as pjoin
import scipy.io as sio
data_dir = pjoin(dirname(sio.__file__), 'matlab', 'tests', 'data')
mat_fname = pjoin(data_dir, 'testdouble_7.4_GLNX86.mat')
mat_contents = sio.loadmat(mat_fname)

Możesz użyć powyższego kodu, aby odczytać domyślnie zapisany plik .mat w Pythonie.

Sameer Gadekar
źródło