Leia arquivos .mat em Python

383

É possível ler arquivos .mat binários do MATLAB em Python?

Vi que o SciPy alegou suporte à leitura de arquivos .mat, mas não obtive êxito. Instalei o SciPy versão 0.7.0 e não consigo encontrar o loadmat()método.

Gilad Naor
fonte

Respostas:

517

É necessária uma importação, import scipy.io...

import scipy.io
mat = scipy.io.loadmat('file.mat')
Gilad Naor
fonte
6
Tutorial oficial SciPy.io: docs.scipy.org/doc/scipy/reference/tutorial/io.html
Franck Dernoncourt
18
O scipy não suporta arquivos mat v7.3 (consulte as notas aqui ). Veja a resposta de vikrantt para solução.
texnic
no entanto, você pode salvar arquivos mat como versões anteriores. consulte: mathworks.com/help/matlab/import_export/mat-file-versions.html (cabeçalho: 'Salvar na versão do arquivo MAT de Nondefault')
watsonic
5
por exemplosave('myfile.mat','-v7')
watsonic
149

Nem funciona scipy.io.savematnem scipy.io.loadmatpara matrizes MATLAB versão 7.3. Mas a parte boa é que os arquivos do MATLAB versão 7.3 são conjuntos de dados hdf5. Para que possam ser lidos usando várias ferramentas, incluindo o NumPy .

Para Python, você precisará da h5pyextensão, que requer HDF5 no seu 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
fonte
6
Isso funciona bem, se você usar o sinalizador '-v7.3' no Matlab ao salvar seus dados. O uso do padrão save(pelo menos no Matlab R2014b) resulta em um arquivo que não pode ser lido usando a técnica acima. Se você usar o sinalizador '-v7.3', os dados numéricos poderão ser lidos perfeitamente.
chipaudette
3
Sim, foi o que eu disse no meu post. Você precisa usar -v7.3 enquanto salva no Matlab. Você deve fazer isso de qualquer maneira, pois ele usa um formato melhor / mais suportado / padronizado.
vikrantt
4
Você poderia explicar qual é a relação entre f e dados no seu exemplo? Como posso mover f para uma matriz numpy?
heracho
Salve uma variável com este comando no prompt:save('filename', '-v7.3', 'var1');
Kevin Katzke
23

Primeiro salve o arquivo .mat como:

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

Depois disso, em Python, use a loadmatfunção usual :

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

Existe um bom pacote chamado mat4pyque pode ser facilmente instalado usando

pip install mat4py

É fácil de usar (no site):

Carregar dados de um arquivo MAT

A função loadmatcarrega todas as variáveis ​​armazenadas no arquivo MAT em uma estrutura de dados Python simples, usando apenas objetos dicte Python list. Matrizes numéricas e de célula são convertidas em listas aninhadas ordenadas por linhas. Matrizes são compactadas para eliminar matrizes com apenas um elemento. A estrutura de dados resultante é composta por tipos simples que são compatíveis com o JSON formato .

Exemplo: Carregue um arquivo MAT em uma estrutura de dados Python:

from mat4py import loadmat

data = loadmat('datafile.mat')

A variável dataé a dictcom as variáveis ​​e os valores contidos no arquivo MAT.

Salvar uma estrutura de dados Python em um arquivo MAT

Dados Python podem ser salvos em um arquivo MAT, com a função savemat. Dados tem que ser estruturada da mesma forma que para loadmat, ou seja, deve ser composta de tipos de dados simples, como dict, list, str, int, efloat .

Exemplo: Salve uma estrutura de dados Python em um arquivo MAT:

from mat4py import savemat

savemat('datafile.mat', data)

O parâmetro datadeve ser a dictcom as variáveis.

Cleb
fonte
Note que o mat4py fornece uma árvore de dicionários, listas, listas de listas do tipo json ... - sem numpy. ( mat4py/cmd.py my.matEscritas my.json, 1 linha longa.)
denis
11
@denis: Sim, isso também é mencionado acima. Mas um bom argumento: eu geralmente gosto dessa estrutura, por exemplo, em aplicativos da Web, pois matrizes numpy não são serializáveis ​​em JSON .
cleb
Encontro:mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files
s2t2 19/07/19
@ s2t2: nunca tive esse problema antes. Qual versão do matlab e qual versão scipy você está usando?
cleb
ParseError: Tamanho inesperado do nome do campo: 43
Aleksejs Fomins
13

Tendo o MATLAB 2014b ou mais recente instalado, o mecanismo MATLAB para Python poderia ser usado:

import matlab.engine
eng = matlab.engine.start_matlab()
content = eng.load("example.mat", nargout=1)
Daniel
fonte
Eu recebi este erro: ModuleNotFoundError: Nenhum módulo chamado 'pylab'.
Chovendo
3
Você recebeu o erro ao tentar estas respostas? Isso é estranho, ele não usa o pylab.
Daniel
11

Lendo o arquivo

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

Inspecionando o tipo de variável MAT

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

As chaves dentro do dicionário são variáveis ​​MATLAB e os valores são os objetos atribuídos a essas variáveis .

Daksh
fonte
7

Existe também o MATLAB Engine for Python do próprio MathWorks. Se você possui o MATLAB, vale a pena considerar isso (não tentei, mas possui muito mais funcionalidade do que apenas ler arquivos do MATLAB). No entanto, não sei se é permitido distribuí-lo a outros usuários (provavelmente não será um problema se essas pessoas tiverem MATLAB. Caso contrário, talvez o NumPy seja o caminho certo a seguir?).

Além disso, se você quiser fazer o básico, o MathWorks fornece (se o link mudar, tente pesquisar no google matfile_format.pdfou em seu título MAT-FILE Format) uma documentação detalhada sobre a estrutura do formato do arquivo. Não é tão complicado quanto eu pensava, mas obviamente, esse não é o caminho mais fácil. Também depende de quantos recursos dos .mat-files você deseja suportar.

Eu escrevi um script Python "pequeno" (cerca de 700 linhas) que pode ler alguns .matarquivos básicos . Não sou especialista em Python nem iniciante e demorei cerca de dois dias para escrevê-lo (usando a documentação do MathWorks vinculada acima). Eu aprendi muitas coisas novas e foi bastante divertido (na maioria das vezes). Como escrevi o script Python no trabalho, receio não poder publicá-lo ... Mas posso dar alguns conselhos aqui:

  • Leia primeiro a documentação.
  • Use um editor hexadecimal (como HxD ) e procure um .matarquivo de referência que você deseja analisar.
  • Tente descobrir o significado de cada byte salvando os bytes em um arquivo .txt e anote cada linha.
  • Use classes para economizar a cada elemento de dados (tais como miCOMPRESSED, miMATRIX, mxDOUBLE, ou miINT32)
  • A .matestrutura -files 'é ideal para salvar os elementos de dados em uma estrutura de dados em árvore; cada nó tem uma classe e subnós
mozzbozz
fonte
9
Essa é uma documentação maluca fornecida pelo mathworks. 40 páginas explicando o formato, sem mencionar que é um subconjunto do 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)

Você pode usar o código acima para ler o arquivo .mat salvo padrão no Python.

Sameer Gadekar
fonte