godfreap godfreap - 2 months ago 7
Python Question

Using scipy.io.savemat to Save Nested Lists

This is relating to my last question, which can be found here. I'm dealing with lists similar to the list I describe in that link as markerList - so a list with three levels. I need to save this information as a .mat file, but I can't get it to save in the right type. When using scipy.io.savemat, it saves the list as a 200x40x2 single, when it should be a set of 200 cells, each containing a 40x2 cell.

The code I'm using to save this is:

matdict = dict(markers = (markerList), sorted = (finalStack))
scipy.io.savemat('C:\pathname\\sortedMarkers.mat', matdict)

What is confusing to me is that it saves markerList in the correct format (1x200 cell, each a cell of varying size), but not finalStack (saved as a 200 x 40 x 2 single). On top of that, before I had figured out the rest of this code, it would save finalStack correctly - which makes me think that perhaps it saves as a cell when the data it is saving isn't uniform in size. (finalStack is uniform in size; markerList is not.)

Is there a way to save a complicated data structure like this as a .mat file?


As per savemat documentation, convert into a numpy array of 'objects':

from scipy.io import savemat
import numpy

a = numpy.array([[1,2,3],[1,2,3]])
b = numpy.array([[2,3,4],[2,3,4]])
c = numpy.array([[3,4,5],[3,4,5]])
L = [a,b,c]

FrameStack = numpy.empty((len(L),), dtype=numpy.object)
for i in range(len(L)):
    FrameStack[i] = L[i]

savemat("myfile.mat", {"FrameStack":FrameStack})

In octave:

>> load myfile.mat 

>> whos FrameStack
Variables in the current scope:

   Attr Name            Size                     Bytes  Class
   ==== ====            ====                     =====  ===== 
        FrameStack      1x3                        144  cell

Total is 3 elements using 144 bytes

>> whos FrameStack{1}
Variables in the current scope:

   Attr Name               Size                     Bytes  Class
   ==== ====               ====                     =====  ===== 
        FrameStack{1}      2x3                         48  int64

Total is 6 elements using 48 bytes