Читать файлы .mat в Python

383

Можно ли читать двоичные файлы MATLAB .mat в Python?

Я видел, что SciPy якобы поддерживает чтение файлов .mat, но мне это не удается. Я установил SciPy версии 0.7.0 и не могу найти loadmat()метод.

Гилад Наор
источник

Ответы:

517

Требуется импорт, import scipy.io...

import scipy.io
mat = scipy.io.loadmat('file.mat')
Гилад Наор
источник
6
Официальное руководство по SciPy.io: docs.scipy.org/doc/scipy/reference/tutorial/io.html
Франк Дернонкур,
18
scipy не поддерживает mat-файлы v7.3 (см. примечания здесь ). Смотрите ответ от vikrantt для решения.
texnic
тем не менее, вы можете сохранить mat-файлы как более ранние версии. см. mathworks.com/help/matlab/import_export/mat-file-versions.html (заголовок: «Сохранить в версию файла MAT по умолчанию»)
watsonic
5
напр.save('myfile.mat','-v7')
watsonic
150

Ни scipy.io.savemat, ни scipy.io.loadmatработать для массивов MATLAB версии 7.3. Но хорошо то, что файлы MATLAB версии 7.3 являются наборами данных hdf5. Таким образом, их можно прочитать с помощью ряда инструментов, включая NumPy .

Для Python вам понадобится h5pyрасширение, которое требует HDF5 в вашей системе.

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
источник
6
Это прекрасно работает, если вы используете флаг '-v7.3' в Matlab при сохранении ваших данных. Использование по умолчанию save(по крайней мере, в Matlab R2014b) приводит к файлу, который не может быть прочитан с использованием описанной выше техники. Если вы используете флаг '-v7.3', числовые данные могут быть прочитаны очень хорошо.
chipaudette
3
Да, это то, что я сказал в своем посте. Вам нужно использовать -v7.3 при сохранении в Matlab. Вы должны сделать это в любом случае, поскольку он использует лучший / более поддерживаемый / стандартизированный формат.
Викрантт
4
Не могли бы вы объяснить, какова связь между f и данными в вашем примере? Как я могу переместить f в массив NumPy?
герачо
Сохраните переменную с помощью этой команды из командной строки:save('filename', '-v7.3', 'var1');
Кевин Кацке
23

Сначала сохраните файл .mat как:

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

После этого в Python используйте обычную loadmatфункцию:

import scipy.io as sio
test = sio.loadmat('test.mat')
Бхану Пратап Сингх
источник
15

Есть хороший пакет, mat4pyкоторый можно легко установить с помощью

pip install mat4py

Это просто использовать (с сайта):

Загрузить данные из MAT-файла

Функция loadmatзагружает все переменные, хранящиеся в MAT-файле, в простую структуру данных Python, используя только Python dictи listобъекты. Числовые массивы и массивы ячеек преобразуются в упорядоченные вложенные списки. Массивы сжимаются, чтобы исключить массивы только с одним элементом. Результирующая структура данных состоит из простых типов, совместимых с форматом JSON .

Пример: загрузка MAT-файла в структуру данных Python:

from mat4py import loadmat

data = loadmat('datafile.mat')

Переменная data- это dictпеременные и значения, содержащиеся в MAT-файле.

Сохранить структуру данных Python в MAT-файл

Данные Python могут быть сохранены в MAT-файл с помощью функции savemat. Данные должны быть структурированы таким же образом , как и для loadmat, т.е. она должна состоять из простых типов данных, как dict, list, str, int, и float.

Пример: сохранить структуру данных Python в MAT-файл:

from mat4py import savemat

savemat('datafile.mat', data)

Параметр dataдолжен быть dictс переменными.

Cleb
источник
Обратите внимание, что mat4py дает вам json-подобное дерево диктов, списков, списков списков ... - вообще ничего не было. ( mat4py/cmd.py my.matпишет my.json, 1 длинная строка.)
Денис
1
@denis: Да, это также указано выше. Но на самом деле это хороший момент: мне обычно нравится эта структура, например, в веб-приложениях, поскольку массивы не являются сериализуемыми в JSON .
Клеб
mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files
Обнаружено
@ s2t2: никогда не сталкивался с этой проблемой раньше. Какую версию Matlab и какую версию Scipy вы используете?
Клеб
ParseError: Неожиданная длина имени поля: 43
Алексей Фоминс
13

Установив MATLAB 2014b или новее, движок MATLAB для Python можно использовать:

import matlab.engine
eng = matlab.engine.start_matlab()
content = eng.load("example.mat", nargout=1)
Даниил
источник
Я получил эту ошибку: ModuleNotFoundError: Нет модуля с именем 'pylab'.
дождь
3
Вы получили ошибку при попытке ответить на этот вопрос? Это странно, он не использует pylab.
Даниэль
11

Чтение файла

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

Проверка типа переменной MAT

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

В ключах внутри словаря являются MATLAB переменными , и значения являются объектами , назначенными для этих переменных .

Дакш
источник
7

Существует также движок MATLAB для Python от самой MathWorks. Если у вас есть MATLAB, об этом стоит подумать (я сам не пробовал, но у него гораздо больше функциональности, чем просто чтение файлов MATLAB). Тем не менее, я не знаю, разрешено ли распространять его среди других пользователей (вероятно, это не проблема, если у этих людей есть MATLAB. В противном случае, возможно, NumPy - правильный путь?).

Кроме того, если вы хотите сделать все основы самостоятельно, MathWorks предоставляет (если ссылка поменяется, попробуйте поискать в Google matfile_format.pdfили ее заголовок MAT-FILE Format) подробную документацию о структуре формата файла. Это не так сложно, как я лично думал, но, очевидно, это не самый простой путь. Это также зависит от того, сколько функций.mat -файлов вы хотите поддерживать.

Я написал «маленький» (около 700 строк) скрипт на Python, который может читать некоторые базовые .matфайлы. Я не эксперт по Python и не новичок, и на его написание у меня ушло около двух дней (с использованием документации MathWorks, ссылки на которую приведены выше). Я узнал много нового, и это было довольно весело (большую часть времени). Поскольку я написал скрипт Python на работе, я боюсь, что не могу его опубликовать ... Но я могу дать здесь несколько советов:

  • Сначала прочитайте документацию.
  • Используйте шестнадцатеричный редактор (например, HxD ) и посмотрите на .matфайл- ссылку, который вы хотите проанализировать.
  • Попробуйте выяснить значение каждого байта, сохранив байты в файл .txt и аннотируя каждую строку.
  • Используйте классы для сохранения каждого элемента данных (например miCOMPRESSED, miMATRIX, mxDOUBLEили miINT32)
  • Структура .mat-files оптимальна для сохранения элементов данных в древовидной структуре данных; каждый узел имеет один класс и подузлы
mozzbozz
источник
9
Это какая-то сумасшедшая документация, предоставленная mathworks. 40 страниц, объясняющих формат, не говоря уже о том, что это подмножество HDF5.
Даниэль
-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)

Вы можете использовать приведенный выше код для чтения сохраненного файла .mat по умолчанию в Python.

Самир Гадекар
источник