Read .mat files in Python

530,262

Solution 1

An import is required, import scipy.io...

import scipy.io
mat = scipy.io.loadmat('file.mat')

Solution 2

Neither scipy.io.savemat, nor scipy.io.loadmat work for MATLAB arrays version 7.3. But the good part is that MATLAB version 7.3 files are hdf5 datasets. So they can be read using a number of tools, including NumPy.

For Python, you will need the h5py extension, which requires HDF5 on your system.

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

Solution 3

First save the .mat file as:

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

After that, in Python, use the usual loadmat function:

import scipy.io as sio
test = sio.loadmat('test.mat')

Solution 4

There is a nice package called mat4py which can easily be installed using

pip install mat4py

It is straightforward to use (from the website):

Load data from a MAT-file

The function loadmat loads all variables stored in the MAT-file into a simple Python data structure, using only Python’s dict and list objects. Numeric and cell arrays are converted to row-ordered nested lists. Arrays are squeezed to eliminate arrays with only one element. The resulting data structure is composed of simple types that are compatible with the JSON format.

Example: Load a MAT-file into a Python data structure:

from mat4py import loadmat

data = loadmat('datafile.mat')

The variable data is a dict with the variables and values contained in the MAT-file.

Save a Python data structure to a MAT-file

Python data can be saved to a MAT-file, with the function savemat. Data has to be structured in the same way as for loadmat, i.e. it should be composed of simple data types, like dict, list, str, int, and float.

Example: Save a Python data structure to a MAT-file:

from mat4py import savemat

savemat('datafile.mat', data)

The parameter data shall be a dict with the variables.

Solution 5

Having MATLAB 2014b or newer installed, the MATLAB engine for Python could be used:

import matlab.engine
eng = matlab.engine.start_matlab()
content = eng.load("example.mat", nargout=1)
Share:
530,262
Gilad Naor
Author by

Gilad Naor

Current: Facebook Engineering Manager in Content Integrity. Previous: Amazon · Bright Source Energy · Intel · Quasars Demo Group

Updated on May 27, 2021

Comments

  • Gilad Naor
    Gilad Naor almost 3 years

    Is it possible to read binary MATLAB .mat files in Python?

    I've seen that SciPy has alleged support for reading .mat files, but I'm unsuccessful with it. I installed SciPy version 0.7.0, and I can't find the loadmat() method.

  • texnic
    texnic almost 10 years
    scipy does not support v7.3 mat-files (see notes here). See the answer by vikrantt for solution.
  • watsonic
    watsonic about 9 years
    however, you can save mat-files as earlier versions. see: mathworks.com/help/matlab/import_export/mat-file-versions.ht‌​ml (header: 'Save to Nondefault MAT-File Version')
  • watsonic
    watsonic about 9 years
    e.g. save('myfile.mat','-v7')
  • chipaudette
    chipaudette almost 9 years
    This works fine, if you use the '-v7.3' flag in Matlab when saving out your data. Using the default save (at least in Matlab R2014b) results in a file that cannot be read using the technique above. If you do use the '-v7.3' flag, the numeric data can be read just fine.
  • vikrantt
    vikrantt almost 9 years
    Yes, that's what I said in my post. You need to use -v7.3 while saving in Matlab. You should do that anyways as it uses a better/more supported/standardized format.
  • Daniel
    Daniel over 8 years
    That's a somehow crazy documentation provided by mathworks. 40 pages explaining the format, without mentioning that it is a subset of HDF5.
  • heracho
    heracho almost 7 years
    Could you please explain what is the relation between f and data in your example? How can I move f to a numpy array?
  • Kevin Katzke
    Kevin Katzke almost 7 years
    Save a variable with this command from the prompt: save('filename', '-v7.3', 'var1');
  • VimNing
    VimNing almost 6 years
    I got this error: ModuleNotFoundError: No module named 'pylab'.
  • Daniel
    Daniel almost 6 years
    You got the error when trying this answers? That is odd, it does not use pylab.
  • denis
    denis over 5 years
    Note that mat4py gives you a json-like tree of dicts, lists, lists of lists ... -- no numpy at all. (mat4py/cmd.py my.mat writes my.json, 1 long line.)
  • Cleb
    Cleb over 5 years
    @denis: Yes, that's also stated above. But a good point indeed: I usually like this structure, e.g. in web applications as numpy arrays are not JSON serializable.
  • s2t2
    s2t2 almost 5 years
    Encountered: mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files
  • Cleb
    Cleb almost 5 years
    @s2t2: never ran into this issue before. What matlab version and which scipy version are you using?
  • Aleksejs Fomins
    Aleksejs Fomins about 4 years
    ParseError: Unexpected field name length: 43
  • Cleb
    Cleb about 4 years
    @AleksejsFomins: Probably best to open a new question and link to this thread; then it will be easier to help (make sure to provide all info needed to reproduce the error).
  • devspartan
    devspartan almost 4 years
    How would i even know that it contains data under data/variable1 ??
  • Chachni
    Chachni almost 4 years
    @s2t2 mat4py cannot read the new matlab format from version 7.3, which is encoded as hdf5.
  • Packard CPW
    Packard CPW over 3 years
    @devSpartan f.keys() will show you what you can access
  • Ramin Melikov
    Ramin Melikov over 3 years
    "Unable to open file (file signature not found)"
  • ThatNewGuy
    ThatNewGuy about 3 years
    @heracho f is the file object that lets you read data from the hdf5 file. It's similar to using f = open('myfile.txt') to read a text file.
  • ThatNewGuy
    ThatNewGuy about 3 years
    @vikrantt This is a great solution for reading a struct but it does not work for a Matlab table. To read tables, you can't use the save function. Instead, you need to utilize the h5create and h5write functions.
  • emilaz
    emilaz almost 3 years
    At least for .mat files generated with MATLAB, this will result in a UnicodeDecodeError.
  • MrCrHaM
    MrCrHaM almost 3 years
    @emilaz This is expected. np.loadtxt is only meant for .mat files generated by Octave.
  • emilaz
    emilaz almost 3 years
    Yes, I just put it there as clarification for future people looking at this :)
  • SjonTeflon
    SjonTeflon over 2 years
    Also note that mat4py does not allow to read complex valued .mat files
  • nKandel
    nKandel about 2 years
    The 2 things that it did better are: it preserve the mat object dimension and the loaded object was in NumPy array. Thanks
  • Abrar_11648
    Abrar_11648 about 2 years
    I faced this issue: "mat4py.loadmat.ParseError: Can only read from Matlab level 5 MAT-files"
  • panter
    panter about 2 years
    I'm glad it helped :)
  • ZaydH
    ZaydH about 2 years
    Updated link to the SciPy.io tutorial docs.scipy.org/doc/scipy/tutorial/io.html @FranckDernoncourt
  • LightCC
    LightCC almost 2 years
    For the record, this answer requires a valid Matlab installation and license - it runs Matlab in the background to accomplish the read. And there may be limitations on what format you get the items in that need further work to make them readable. For example, Simulink.Bus objects come in as a "matlab object" and must be processed further, with issues if you want to extract the Bus Element objects.