Search code examples
pythonmatlabnumpyscipymat-file

ndim in numpy array loaded with scipy.io.loadmat?


Using SciPy and MATLAB, I'm having trouble reconstructing an array to match what is given from a MATLAB cell array loaded using scipy.io.loadmat().

For example, say I create a cell containing a pair of double arrays in MATLAB and then load it using scipy.io (I'm using SPM to do imaging analyses in conjunction with pynifti and the like)

MATLAB

>> onsets{1} = [0 30 60 90]
>> onsets{2} = [15 45 75 105]

Python

>>> import scipy.io as scio
>>> mat = scio.loadmat('onsets.mat')
>>> mat['onsets'][0]
array([[[ 0 30 60 90]], [[ 15  45  75 105]]], dtype=object)

>>> mat['onsets'][0].shape

(2,)

My question is this: Why does this numpy array have the shape (2,) instead of (2,1,4)? In real life I'm trying to use Python to parse a logfile and build these onsets cell arrays, so I'd like to be able to build them from scratch.

When I try to build the same array from the printed output, I get a different shape back:

>>> new_onsets = array([[[ 0, 30, 60, 90]], [[ 15,  45,  75, 105]]], dtype=object)
array([[[0, 30, 60, 90]],

       [[15, 45, 75, 105]]], dtype=object)

>>> new_onsets.shape
(2,1,4)

Unfortunately, the shape (vectors of doubles in a cell array) is coded in a spec upstream, so I need to be able to get this saved exactly in this format. Of course, it's not a big deal since I could just write the parser in MATLAB, but it would be nice to figure out what's going on and add a little to my [minuscule] knowledge of numpy.


Solution

  • Travis from the scipy mailing list responded that the right way to build this is to create the structure first, then populate the arrays:

    http://article.gmane.org/gmane.comp.python.scientific.user/31760

    > You could build what you saw before with: 
    > 
    > new_onsets = empty((2,), dtype=object) 
    > new_onsets[0] = array([[0, 30, 60, 90]]) 
    > new_onsets[1] = array([[15, 45, 75, 105]])