Question

I am very new to matlab and python and need to use some values in python from the matlab cell array.

I have a cell array of integers that after i execute this line of code and print the result, i get this:

a = loadmat('file.mat')
print a

{'__version__': '1.0', '__header__': 'MATLAB 5.0 MAT-file, Platform: PCWIN, Created on: Wed Sep 21 15:30:15 2011', 'juncForward_c': array([[ [[ [[ ([[30]], **[[91], [87]]**, [[3]], [[2.2455372690184494, 3.6052402625905993, 5.5884470309828833]], [[14.0, 4.0, 15.4]], [[-1, -1, 2]], [[91, 89, 93], [88, 85, 86]], [[500, 500, 5]], [[1, 2, 3]], [[11.133333333333333]], **[[4]]**, [[1]], [[1]], [[1.0], [20.365168528421695]])]]

[[ ([[30]], **[[99], [80]]**, [[3]], [[4.0376480381611373, 2.3561944901923448, 6.0857897473297058]], [[10.0, 15.4, 16.600000000000001]], [[-1, 1, 3]], [[98, 98, 100], [79, 81, 80]], [[500, 6, 33]], [[1, 2, 3]], **[[14]]**, [[2]], [[1]], [[1]], [[2.0], [6.6573267908372973]])]]

and the print out continues on.

Could someone explain to me how the cell array is arranged? (so how many dimensions is the above?)

I then have a few questions: 1) Within this cell array, there are variables 'label' and 'coordinates' that are assigned to one array/cell (i dont know which is the actual term to use) -- the values in bold. I would like to write in Python to access this values. How should I go about it?

2) To test, I tried this -> juncInfoF = a.get('juncForward_c') and when i try to print juncInfoF, it prints 'None'. Why is that so? I am puzzled because previously when i tried this, it works. I could even do this -> print juncInfo[0][9][0][0]. but now I cannot even do any of the above.

Was it helpful?

Solution

I imagine loadmat('file.mat') returns an instance of a shelve-class, that is inherited from the dict class. I assume you are using the loadmat function from scipy.io?

from scipy.io import loadmat

The scipy doc only mentions loadmat() returns a dictionary, but my guess is that the returned object a in your example is an open shelve-file, and you can no longer access its content when a is closed, which might happen for several reasons apart from calling a.close() mannually.

To prevent this, copy all data into a real dictionary first, while loading this data:

mat_dict = {}
mat_dict.update(loadmat('file.mat'))

Now you can retrieve all keys and values from mat_dict:

a = mat_dict['juncForward_c']
print(a.shape) # should work now

note that this is a valid solution as long as you are testing and figuring out what the mat_dict data is all about. In your script/model/function you would tipically load only the part of the shelve dict that you want, and then close the file explicitly:

f = loadmat('file.mat')
a = f['juncForward_c']
f.close()

I don't know if the with statement works (shelve does not support it as yet), you'll have to test it, but it should handle closing even when an exception is thrown during loading of a:

with loadmat('file.mat') as f:
    a = f['juncForward_c']

edit: subclass from numpy array to add additional attributes

import numpy as np

class MatArray(np.array):
    def __init__(self, filepath):
        f = loadmat(filepath)
        np.array.__init__(self, f['juncForward_c'])
        self.version = f['__version__']
        self.header = f['__header__']
        f.close() 

so now if you want your array resembling the matlab structure, you do:

>>> a = MatArray('myfile.mat')
>>> a.header
'MATLAB 5.0 MAT-file, Platform: PCWIN, Created on: Wed Sep 21 15:30:15 2011'
>>> a.shape

etc

OTHER TIPS

If in your mat file there are only cell arrays with list of integers or strings, I wrote a generic code for that. For example, in matlab you can do something like that:

names = cell(1, N);
indices = cell(1, N);
for ind=1:N
    names{ind} = *some_value*;
    indices{ind} = *some_array*;
save('names_and_indices.mat', 'names', 'indices');

Here you can find how to read this mat file in python.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top