Leer archivos .mat en Python

383

¿Es posible leer archivos binarios MATLAB .mat en Python?

He visto que SciPy presuntamente admite la lectura de archivos .mat, pero no lo he logrado. Instalé SciPy versión 0.7.0, y no puedo encontrar el loadmat()método.

Gilad Naor
fuente

Respuestas:

517

Se requiere una importación, import scipy.io...

import scipy.io
mat = scipy.io.loadmat('file.mat')
Gilad Naor
fuente
66
Tutorial oficial de SciPy.io: docs.scipy.org/doc/scipy/reference/tutorial/io.html
Franck Dernoncourt
18
scipy no admite archivos mat v7.3 (vea las notas aquí ). Vea la respuesta de vikrantt para la solución.
texnic
sin embargo, puede guardar archivos mat como versiones anteriores. ver: mathworks.com/help/matlab/import_export/mat-file-versions.html (encabezado: 'Guardar en versión de archivo MAT no
predeterminada
55
por ejemplosave('myfile.mat','-v7')
watsonic
150

Ni scipy.io.savemat, ni scipy.io.loadmatfuncionan para matrices MATLAB versión 7.3. Pero lo bueno es que los archivos MATLAB versión 7.3 son conjuntos de datos hdf5. Por lo tanto, se pueden leer con una serie de herramientas, incluida NumPy .

Para Python, necesitará la h5pyextensión, que requiere HDF5 en su sistema.

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
fuente
66
Esto funciona bien si usa el indicador '-v7.3' en Matlab al guardar sus datos. El uso del valor predeterminado save(al menos en Matlab R2014b) da como resultado un archivo que no se puede leer utilizando la técnica anterior. Si utiliza el indicador '-v7.3', los datos numéricos se pueden leer muy bien.
chipaudette
3
Sí, eso es lo que dije en mi publicación. Debe usar -v7.3 mientras guarda en Matlab. De todos modos, debe hacerlo, ya que utiliza un formato mejor / más compatible / estandarizado.
Vikrantt
44
¿Podría explicar cuál es la relación entre f y datos en su ejemplo? ¿Cómo puedo mover f a una matriz numpy?
heracho
Guarde una variable con este comando desde el indicador:save('filename', '-v7.3', 'var1');
Kevin Katzke
23

Primero guarde el archivo .mat como:

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

Después de eso, en Python, use la loadmatfunción habitual :

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

Hay un buen paquete llamado mat4pyque se puede instalar fácilmente usando

pip install mat4py

Es fácil de usar (desde el sitio web):

Cargar datos de un archivo MAT

La función loadmatcarga todas las variables almacenadas en el archivo MAT en una estructura de datos Python simple, usando solo Python dicty listobjetos. Las matrices numéricas y de celdas se convierten en listas anidadas ordenadas por filas. Las matrices se comprimen para eliminar las matrices con un solo elemento. La estructura de datos resultante se compone de tipos simples que son compatibles con el formato JSON .

Ejemplo: Cargue un archivo MAT en una estructura de datos de Python:

from mat4py import loadmat

data = loadmat('datafile.mat')

La variable dataes a dictcon las variables y valores contenidos en el archivo MAT.

Guardar una estructura de datos de Python en un archivo MAT

Python de datos se pueden guardar en un archivo MAT, con la función savemat. De datos tiene que estar estructurado de la misma manera que para loadmat, es decir, debe estar compuesta de tipos de datos simples, como dict, list, str, int, yfloat .

Ejemplo: guardar una estructura de datos de Python en un archivo MAT:

from mat4py import savemat

savemat('datafile.mat', data)

El parámetro dataserá a dictcon las variables.

Cleb
fuente
Tenga en cuenta que mat4py le ofrece un árbol de dictos, listas, listas de listas ... como json, nada molesto. ( mat4py/cmd.py my.matescribe my.json, 1 línea larga)
denis
1
@denis: Sí, eso también se indicó anteriormente. Pero un buen punto de hecho: generalmente me gusta esta estructura, por ejemplo, en aplicaciones web ya que las matrices numpy no son serializables JSON .
Cleb
Encontrado:mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files
s2t2
@ s2t2: nunca me encontré con este problema antes. ¿Qué versión de matlab y qué versión scipy estás usando?
Cleb
ParseError: Longitud de nombre de campo inesperada: 43
Aleksejs Fomins
13

Con MATLAB 2014b o una versión más reciente instalada, se podría usar el motor MATLAB para Python :

import matlab.engine
eng = matlab.engine.start_matlab()
content = eng.load("example.mat", nargout=1)
Daniel
fuente
Recibí este error: ModuleNotFoundError: Ningún módulo llamado 'pylab'.
Llueve el
3
¿Recibiste el error al intentar estas respuestas? Eso es extraño, no usa pylab.
Daniel
11

Leyendo el archivo

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

Inspeccionar el tipo de variable MAT

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

Las claves dentro del diccionario son variables de MATLAB , y los valores son los objetos asignados a esas variables .

Daksh
fuente
7

También está el motor MATLAB para Python de MathWorks. Si tiene MATLAB, vale la pena considerarlo (no lo he probado yo mismo, pero tiene mucha más funcionalidad que solo leer archivos de MATLAB). Sin embargo, no sé si está permitido distribuirlo a otros usuarios (probablemente no sea un problema si esas personas tienen MATLAB. De lo contrario, ¿quizás NumPy es el camino correcto?).

Además, si desea hacer todo lo básico usted mismo, MathWorks proporciona (si el enlace cambia, intente buscar en google matfile_format.pdfo su título MAT-FILE Format) una documentación detallada sobre la estructura del formato de archivo. No es tan complicado como pensaba personalmente, pero obviamente, esta no es la forma más fácil de hacerlo. También depende de cuántas características del.mat archivos desee admitir.

He escrito un script Python "pequeño" (aproximadamente 700 líneas) que puede leer algunos .matarchivos básicos . No soy ni un experto en Python ni un principiante y me llevó cerca de dos días escribirlo (usando la documentación de MathWorks vinculada anteriormente). Aprendí muchas cosas nuevas y fue bastante divertido (la mayoría de las veces). Como he escrito el script de Python en el trabajo, me temo que no puedo publicarlo ... Pero puedo dar algunos consejos aquí:

  • Primero lea la documentación.
  • Use un editor hexadecimal (como HxD ) y busque un .matarchivo de referencia que desee analizar.
  • Intente averiguar el significado de cada byte guardando los bytes en un archivo .txt y anote cada línea.
  • Utilizar las clases para guardar cada elemento de datos (como miCOMPRESSED, miMATRIX, mxDOUBLE, o miINT32)
  • La .matestructura de los archivos es óptima para guardar los elementos de datos en una estructura de datos de árbol; cada nodo tiene una clase y subnodos
mozzbozz
fuente
99
Esa es una documentación un tanto loca proporcionada por Mathworks. 40 páginas que explican el formato, sin mencionar que es un subconjunto 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)

Puede usar el código anterior para leer el archivo .mat guardado predeterminado en Python.

Sameer Gadekar
fuente