6

I have a complex data structure

data = {}
temp = {}

data['bigdata'] = temp;

After this I copy 'key' and 'data' values from some other data structure into temp, like this

for key in backup.keys():
    temp[key] = []

and

for key in backup.keys():
    for val in backup[key]:
        temp[key].append(val);

After that If I do

sio.savemat(outputMATfile,data,oned_as ='column')

it is giving me error saying

TTypeError: data type not understood

Is it not possible to store a complex dictionary like this in a matlab file, using python ?

0

1 Answer 1

6

edit: Answer (and question somewhat) have changed significantly to be more general. It would still be useful it the asker would tell us what kinds of objects the values in backup are.

The scipy.io.savemat can apparently take a dictionary of dictionaries of arrays, so this structure

from numpy import array
import scipy.io
data = {
    'bigdata' : {
        'a' : array([1, 2, 3]),
        'b' : array([1, 2, 3]),
        'c' : array([1, 2, 3]),
     }
}
scipy.io.savemat('test.mat', data)

loads into matlab as

>> load test.mat
>> bigdata

bigdata = 

    a: [3x1 int64]
    c: [3x1 int64]
    b: [3x1 int64]

I imagine these dictionaries can be nested up to python's recursion limit, since the implementation is recursive. I tested 6 levels of nesting dictionaries. Edit: Now you're asking about a structure like this:

data = {
    'key1' : ['a' : apple, 'b' : banana],
    'key2' : ['c' : crabapple, 'd' : dragonfruit],
    ...
    }

and you haven't specified what apple, banana etc. are. It depends on what data from these Python objects you want in the Matlab objects. I tested a few classes like str (converted to char array), set (failed to convert to array), and list (array if homogeneous, character array if some strings, some numbers). The code looks pretty duck-type-ish, so if these objects have any a common data-holding interface it should get through; I present an excerpt here of the most relevant bit for the matlab5 version:

def to_writeable(source)
    if isinstance(source, np.ndarray):
        return source
    if source is None:
        return None
    # Objects that have dicts
    if hasattr(source, '__dict__'):
        source = dict((key, value) for key, value in source.__dict__.items()
                      if not key.startswith('_'))
    # Mappings or object dicts
    if hasattr(source, 'keys'):
        dtype = []
        values = []
        for field, value in source.items():
            if (isinstance(field, basestring) and
                not field[0] in '_0123456789'):
                dtype.append((field,object))
                values.append(value)
        if dtype:
            return np.array( [tuple(values)] ,dtype)
        else:
            return None
    # Next try and convert to an array
    narr = np.asanyarray(source)
    if narr.dtype.type in (np.object, np.object_) and \
       narr.shape == () and narr == source:
        # No interesting conversion possible
        return None
    return narr
Sign up to request clarification or add additional context in comments.

3 Comments

The closest thing to Python dictionary objects are MATLAB's structures, where the fieldnames are the dictionary keys
I was just writing a semi-pseudo code. Your understanding of the data structure is correct. But the above code you mentioned can be saved using sio.savemat("doom.mat",data,oned_as='column');
@Thomas: +1 in fact, calling scipy.io.savemat('file.mat', data), then loading the file in MATLAB, its indeed of type struct with fieldnames as expected. (BTW I think you have missing commas, I fixed it but got overwritten by your recent edit)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.