Lire les fichiers .mat en Python

383

Est-il possible de lire des fichiers binaires MATLAB .mat en Python?

J'ai vu que SciPy a prétendument pris en charge la lecture des fichiers .mat, mais je n'y parviens pas. J'ai installé SciPy version 0.7.0 et je ne trouve pas la loadmat()méthode.

Gilad Naor
la source

Réponses:

517

Une importation est requise, import scipy.io...

import scipy.io
mat = scipy.io.loadmat('file.mat')
Gilad Naor
la source
6
Tutoriel officiel SciPy.io: docs.scipy.org/doc/scipy/reference/tutorial/io.html
Franck Dernoncourt
18
scipy ne prend pas en charge les fichiers mat v7.3 (voir les notes ici ). Voir la réponse de vikrantt pour la solution.
texnic
cependant, vous pouvez enregistrer les fichiers mat en tant que versions antérieures. voir: mathworks.com/help/matlab/import_export/mat-file-versions.html (en-tête: «Enregistrer dans la version du fichier MAT Nondefault»)
watsonic
5
par exemplesave('myfile.mat','-v7')
watsonic
150

Ni scipy.io.savemat, ni ne scipy.io.loadmatfonctionne pour les baies MATLAB version 7.3. Mais la bonne partie est que les fichiers MATLAB version 7.3 sont des ensembles de données hdf5. Ils peuvent donc être lus à l'aide d'un certain nombre d'outils, y compris NumPy .

Pour Python, vous aurez besoin de l' h5pyextension, qui nécessite HDF5 sur votre système.

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
la source
6
Cela fonctionne très bien, si vous utilisez l'indicateur '-v7.3' dans Matlab lors de la sauvegarde de vos données. L'utilisation de la valeur par défaut save(au moins dans Matlab R2014b) entraîne un fichier qui ne peut pas être lu à l'aide de la technique ci-dessus. Si vous utilisez le drapeau '-v7.3', les données numériques peuvent être lues très bien.
chipaudette
3
Oui, c'est ce que j'ai dit dans mon post. Vous devez utiliser -v7.3 lors de l'enregistrement dans Matlab. Vous devriez le faire de toute façon car il utilise un format meilleur / plus pris en charge / standardisé.
vikrantt
4
Pourriez-vous expliquer quelle est la relation entre f et les données dans votre exemple? Comment puis-je déplacer f vers un tableau numpy?
heracho
Enregistrez une variable avec cette commande à partir de l'invite:save('filename', '-v7.3', 'var1');
Kevin Katzke
23

Enregistrez d'abord le fichier .mat sous:

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

Après cela, en Python, utilisez la loadmatfonction habituelle :

import scipy.io as sio
test = sio.loadmat('test.mat')
Bhanu Pratap Singh
la source
15

Il y a un joli paquet appelé mat4pyqui peut facilement être installé en utilisant

pip install mat4py

Il est simple à utiliser (à partir du site Web):

Charger des données à partir d'un fichier MAT

La fonction loadmatcharge toutes les variables stockées dans le fichier MAT dans une structure de données Python simple, en utilisant uniquement des objets dictet Python list. Les tableaux numériques et cellulaires sont convertis en listes imbriquées rangées. Les tableaux sont compressés pour éliminer les tableaux avec un seul élément. La structure de données résultante est composée de types simples compatibles avec le JSON format .

Exemple: chargez un fichier MAT dans une structure de données Python:

from mat4py import loadmat

data = loadmat('datafile.mat')

La variable dataest un dictavec les variables et les valeurs contenues dans le fichier MAT.

Enregistrer une structure de données Python dans un fichier MAT

Les données Python peuvent être enregistrées dans un fichier MAT, avec la fonction savemat. Les données doivent être structurées de la même manière que pour loadmat, à savoir qu'il devrait être composé de types de données simples, comme dict, list, str, intetfloat .

Exemple: enregistrez une structure de données Python dans un fichier MAT:

from mat4py import savemat

savemat('datafile.mat', data)

Le paramètre datadoit être a dictavec les variables.

Cleb
la source
Notez que mat4py vous donne un arbre de dict, des listes, des listes de listes de type json ... - pas du tout numpy. ( mat4py/cmd.py my.matécrit my.json, 1 longue file.)
denis
1
@denis: Oui, c'est également indiqué ci-dessus. Mais un bon point en effet: j'aime généralement cette structure, par exemple dans les applications web car les tableaux numpy ne sont pas sérialisables JSON .
Cleb
Rencontré:mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files
s2t2
@ s2t2: jamais rencontré ce problème auparavant. Quelle version de matlab et quelle version scipy utilisez-vous?
Cleb
ParseError: Longueur de nom de champ inattendue: 43
Aleksejs Fomins
13

Après avoir installé MATLAB 2014b ou une version plus récente, le moteur MATLAB pour Python pourrait être utilisé:

import matlab.engine
eng = matlab.engine.start_matlab()
content = eng.load("example.mat", nargout=1)
Daniel
la source
J'ai eu cette erreur: ModuleNotFoundError: Aucun module nommé 'pylab'.
Raining
3
Vous avez l'erreur en essayant ces réponses? C'est étrange, il n'utilise pas pylab.
Daniel
11

Lecture du fichier

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

Inspection du type de variable MAT

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

Les clés à l'intérieur du dictionnaire sont des variables MATLAB et les valeurs sont les objets affectés à ces variables .

Daksh
la source
7

Il existe également le moteur MATLAB pour Python de MathWorks lui-même. Si vous avez MATLAB, cela pourrait valoir la peine d'être considéré (je ne l'ai pas essayé moi-même mais il a beaucoup plus de fonctionnalités que la simple lecture de fichiers MATLAB). Cependant, je ne sais pas s'il est autorisé à le distribuer à d'autres utilisateurs (ce n'est probablement pas un problème si ces personnes ont MATLAB. Sinon, NumPy est peut-être la bonne voie à suivre?).

De plus, si vous voulez faire vous-même toutes les bases, MathWorks fournit (si le lien change, essayez de rechercher Google matfile_format.pdfou son titre MAT-FILE Format) une documentation détaillée sur la structure du format de fichier. Ce n'est pas aussi compliqué que je le pensais personnellement, mais évidemment, ce n'est pas la voie la plus simple à suivre. Cela dépend également du nombre de fonctionnalités du.mat fichiers que vous souhaitez prendre en charge.

J'ai écrit un "petit" (environ 700 lignes) script Python qui peut lire des .matfichiers de base . Je ne suis ni un expert Python ni un débutant et il m'a fallu environ deux jours pour l'écrire (en utilisant la documentation MathWorks liée ci-dessus). J'ai appris beaucoup de nouvelles choses et c'était assez amusant (la plupart du temps). Comme j'ai écrit le script Python au travail, j'ai bien peur de ne pas pouvoir le publier ... Mais je peux vous donner quelques conseils ici:

  • Lisez d'abord la documentation.
  • Utilisez un éditeur hexadécimal (tel que HxD ) et recherchez un .matfichier de référence que vous souhaitez analyser.
  • Essayez de comprendre la signification de chaque octet en enregistrant les octets dans un fichier .txt et annotez chaque ligne.
  • Utiliser des classes pour enregistrer chaque élément de données ( par exemple miCOMPRESSED, miMATRIX, mxDOUBLEou miINT32)
  • La .matstructure des fichiers est optimale pour enregistrer les éléments de données dans une structure de données arborescente; chaque nœud a une classe et des sous-nœuds
mozzbozz
la source
9
C'est une documentation quelque peu folle fournie par mathworks. 40 pages expliquant le format, sans mentionner qu'il s'agit d'un sous-ensemble de 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)

Vous pouvez utiliser le code ci-dessus pour lire le fichier .mat enregistré par défaut en Python.

Sameer Gadekar
la source