Saving dictionaries from Python to Matlab with Scipy

孤人 提交于 2021-01-27 13:06:02

问题


I'm finding some problems to save my neat generated data into .mat files. I thought it was more straightforward with Scipy, but it seems I'm getting something wrong.

This is an example of data I want to save:

out = {'features': array([[  5.00088905e+01,   1.51847522e+01,   4.93513862e+01,
          3.76548415e+00,  -3.96946513e+01,  -2.11885850e+01,
          9.85304035e+00,  -6.30005764e+00,   1.19987435e+01,
          3.89762536e+00,  -1.31554755e+00,  -1.66890836e+01,
          4.75289017e-02,   3.65829480e-01,  -4.77872832e-01,
          1.13641908e+00,  -1.08742775e-01,  -2.42751445e-01,
         -1.13054913e-01,   3.39011561e-01,   1.37158960e-01,
         -2.80760116e-01,  -4.15187861e-01,   9.85433526e-02,
         -8.66144928e-02,   9.18260870e-03,  -7.38139130e-01,
          8.04136232e-01,   2.31623188e-02,  -7.88927536e-02,
         -2.17779710e-01,   2.85428986e-01,  -8.16231884e-02,
          1.79710145e-03,  -3.47710145e-01,  -9.84115942e-02,
          3.96077031e+00,   3.29914828e+01,   2.60086805e+01,
          2.44418378e+01,   2.01712577e+01,   1.56827627e+01,
          1.59131122e+01,   1.84134126e+01,   1.63149310e+01,
          1.35579058e+01,   1.15772911e+01,   1.82263123e+01,
          3.96077031e+00,   3.29914828e+01,   2.60086805e+01,
          2.44418378e+01,   2.01712577e+01,   1.56827627e+01,
          1.59131122e+01,   1.84134126e+01,   1.63149310e+01,
          1.35579058e+01,   1.15772911e+01,   1.82263123e+01,
          3.96077031e+00,   3.29914828e+01,   2.60086805e+01,
          2.44418378e+01,   2.01712577e+01,   1.56827627e+01,
          1.59131122e+01,   1.84134126e+01,   1.63149310e+01,
          1.35579058e+01,   1.15772911e+01,   1.82263123e+01]]), 'tags': [['rock', 'metal']]}

It's a single row of a matrix that can be associated with a list of tags (variable in lengths).

The idea was to have a .mat file with the matrix and a cell array of lists. When I go for this:

scipy.io.savemat('./test.mat',out)

results in Matlab for tags vary. For the example above I have a 1x2x5 char matrix

val(:,:,1) =    rm    
val(:,:,2) =    oe    
val(:,:,3) =    ct    
val(:,:,4) =    ka    
val(:,:,5) =     l

If I try for matrix instead than single row vectors, I get a cell array with a cell for every row, but the list is merged and the cell for the specific row would be: rmoectkal.

Il try to explain with an example:

>>> genre_tags_matrix = np.array(genre_tags, dtype=np.object) 
>>> print(genre_tags_matrix) 
[['classical', 'pop'] ['classical'] ['classical'] ['classical']]
>>> out = {'tags' : genre_tags_matrix}
>>> scipy.io.savemat('./test.mat',out)

This is what I see in Matlab:

What exactly is going on? Is there a workaround for this?


回答1:


The issue is that a string in MATLAB and Octave is really just an array of characters, so the following statement is actually a 3D array

[['rock', 'metal']]

If we replace the characters with numbers to make it a little clearer that it's a 3D array we get something like this

[[[1,2,3], [4,5,6]]]

When you save either of these to a .mat file with savemat it's going to be treated as a 3D array.

If you instead want a cell array, you have to manually create a numpy array of numpy objects.

import scipy
import numpy as np

out = {'tags': np.array(['rock', 'metal'], dtype=np.object)}

scipy.io.savemat('test.mat', out)

Then within MATLAB or Octave

data = load('test.mat')
%    tags =
%    {
%      [1,1] = rock
%      [1,2] = metal
%    }

Update

In the case of a nested cell array, each level that you would like to be a cell array must also be a numpy array of numpy objects

out = {'tags': np.array([
            np.array(['classical', 'pop'], dtype=np.object),    # A nested cell array
            'classical', 'classical', 'classical'], dtype=np.object)}


来源:https://stackoverflow.com/questions/41693717/saving-dictionaries-from-python-to-matlab-with-scipy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!