SciPy, input and output in MATLAB

  • Tutorial

SciPy (pronounced sai pay) is a math application package based on the Numpy Python extension. With SciPy, an interactive Python session turns into the same comprehensive data processing and prototyping environment for complex systems like MATLAB, IDL, Octave, R-Lab and SciLab. In this post, I would like to talk about the capabilities of the I / O package, which allows you to work with the Octave and MATLAB data files.


First we import the package as follows:

import as sio

The main procedures of the package, which allow working with MATLAB files:


In order not to violate the MATLAB license agreement, we will work in the GNU Octave environment, which has MATLAB compatible save and load functions. Let's enter the Octave command line:

octave:1> a = 1:12
a =
   1   2   3   4   5   6   7   8   9  10  11  12
octave:2> a = reshape(a, [1 3 4])
a =
ans(:,:,1) =
   1   2   3
ans(:,:,2) =
   4   5   6
ans(:,:,3) =
   7   8   9
ans(:,:,4) =
   10   11   12
octave:3> save -6 octave_a.mat a % MATLAB 6 compatible
octave:4> ls octave_a.mat

The code to import the MATLAB file into Python:

mat_contents = sio.loadmat('octave_a.mat')

    {'__header__': b'MATLAB 5.0 MAT-file, written by Octave 4.2.2, 2019-02-02 20:26:43 UTC',
     '__version__': '1.0',
     '__globals__': [],
     'a': array([[[ 1.,  4.,  7., 10.],
             [ 2.,  5.,  8., 11.],
             [ 3.,  6.,  9., 12.]]])}

oct_a = mat_contents['a']

    array([[[ 1.,  4.,  7., 10.],
            [ 2.,  5.,  8., 11.],
            [ 3.,  6.,  9., 12.]]])


(1, 3, 4)

As you can see, the file is read correctly. Now consider exporting from SciPy to MATLAB:

import numpy as np
vect = np.arange (10)


sio.savemat ('np_vector.mat', {'vect': vect})

Import the Python file into Octave:

octave:8> load np_vector.mat
octave:9> vect
vect =
  0  1  2  3  4  5  6  7  8  9
octave:10> size(vect)
ans =
    1   10

To check the contents of the MATLAB file without reading the data in memory, use the whosmat command:

sio.whosmat ('octave_a.mat')

[('a', (1, 3, 4), 'double')]

The whosmat function returns a list of tuples, one for each array (or other object) contained in the MATLAB file. Each tuple contains the name, file contents, and data type.

MATLAB Structures

MATLAB structures are similar to Python dicts dictionaries. The difference is that the field name must be a string. The field value can be any object.
Recall that MATLAB is an acronym of MATrix Laboratory. Since The main purpose of MATLAB is working with matrices, so all the objects in it are matrices. Even one number is represented as a matrix of size (1, 1).

octave:11> my_struct = struct('field1', 1, 'field2', 2)
my_struct =
  field1 =  1
  field2 =  2
octave:12> save -6 octave_struct.mat my_struct

Download the MATLAB structure in Python:

mat_contents = sio.loadmat('octave_struct.mat')

{'__header__': b'MATLAB 5.0 MAT-file, written by Octave 4.2.2, 2019-02-02 20:34:26 UTC',
 '__version__': '1.0',
 '__globals__': [],
 'my_struct': array([[(array([[1.]]), array([[2.]]))]],
       dtype=[('field1', 'O'), ('field2', 'O')])}

oct_struct = mat_contents['my_struct']

(1, 1)

val = oct_struct[0,0]

(array([[1.]]), array([[2.]]))






dtype([('field1', 'O'), ('field2', 'O')])

In SciPy versions from 0.12.0, the MATLAB structure is returned as numpy structured arrays. The names of the fields in the numpy array are the names of the fields in the MATLAB structure. Field names can be read using the dtype command, as in the example above. Learn more about the structed arrays data types .

Thus, in MATLAB, an array of structures has a size of at least 2D, which is repeated when reading in SciPy. To reduce the dimension to 1, use the squeeze_me parameter:

mat_contents = sio.loadmat ('octave_struct.mat', squeeze_me = True)
oct_struct = mat_contents ['my_struct']


Sometimes it is more convenient to load MATLAB structures as python objects, rather than numpy arrays. To do this, use the parameter struct_as_record = False to load.

mat_contents = sio.loadmat ('octave_struct.mat', struct_as_record = False)
oct_struct = mat_contents ['my_struct']


The struct_as_record = False parameter works fine with the squeeze_me parameter:

mat_contents = sio.loadmat('octave_struct.mat', struct_as_record=False, squeeze_me=True)
oct_struct = mat_contents['my_struct']
oct_struct.shape # выдаст ошибку, т.к. у скаляра нет аттрибута shape

AttributeError                            Traceback (most recent call last)
<ipython-input-23-d41d0a59bb9b> in <module>
      1 mat_contents = sio.loadmat('octave_struct.mat', struct_as_record=False, squeeze_me=True)
      2 oct_struct = mat_contents['my_struct']
----> 3 oct_struct.shape # выдаст ошибку, т.к. это скаляр
AttributeError: 'mat_struct' object has no attribute 'shape'




The easiest way to export structures from python to MATLAB is with the dicts dictionaries:

a_dict = {'field1': 0.5, 'field2': 'a string'}
sio.savemat ('saved_struct.mat', {'a_dict': a_dict})

The MATLAB is loaded as:

octave:21> load saved_struct
octave:22> a_dict
a_dict =
  scalar structure containing the fields:
    field1 =  0.50000
    field2 = a string

You can also export structures from python to MATLAB using numpy arrays:

dt = [('f1', 'f8'), ('f2', 'S10')]
arr = np.zeros ((2,), dtype = dt)

array([(0., b''), (0., b'')], dtype=[('f1', '<f8'), ('f2', 'S10')])

arr [0] ['f1'] = 0.5
arr [0] ['f2'] = 'python'
arr [1] ['f1'] = 99
arr [1] ['f2'] = 'not perl'
sio.savemat ('np_struct_arr.mat', {'arr': arr})

Arrays of cells (cell) MATLAB

Arrays of cells (cell) in MATLAB are similar to python lists. Elements in cell arrays can contain any type of MATLAB object. Also, the cell is very similar to arrays of numpy objects. Consider an example of exporting a cell from MATLAB to numpy.

octave:14> my_cells = {1, [2, 3]}
my_cells =
  [1,1] =  1
  [1,2] =
     2   3
octave:15> save -6 octave_cells.mat my_cells

Let's go back to Python:

mat_contents = sio.loadmat ('octave_cells.mat')
oct_cells = mat_contents ['my_cells']
print (oct_cells.dtype)


val = oct_cells [0,0]


print (val.dtype)


Exporting from numpy to the cell array MATLAB is done using the numpy-array of objects:

obj_arr = np.zeros ((2,), dtype = np.object)
obj_arr [0] = 1
obj_arr [1] = 'a string'

array([1, 'a string'], dtype=object)

sio.savemat ('np_cells.mat', {'obj_arr': obj_arr})

Check the export of a cell from numpy to Octave:

octave:16> load np_cells.mat
octave:17> obj_arr
obj_arr =
  [1,1] = 1
  [2,1] = a string

On this, perhaps, finish. I hope for someone this article will serve as a reason for the integration of research in MATLAB with free software.
Source: scipy documentation

Also popular now: