使用Scipy将Python字典保存到Matlab中

3
我在将我生成的整齐数据保存到.mat文件时遇到了一些问题。我认为使用Scipy更加简单明了,但似乎我做错了什么。
这是我想要保存的数据示例:
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']]}

这是一个与标签列表相关联的矩阵的单行(变量长度)。

想法是使用包含矩阵和列表的单元格数组的.mat文件。当我进行以下操作时:

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

Matlab中标签的结果可能会有所不同。对于上面的示例,我有一个1x2x5字符矩阵。

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

如果我尝试使用矩阵而不是单行向量,则会得到一个单元格数组,其中每一行都有一个单元格,但列表会合并,并且特定行的单元格将为:rmoectkal
我将用一个示例来解释:
>>> 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)

以下是我在Matlab中看到的内容:

matscreen

发生了什么?有没有解决方法?

1个回答

2
问题在于MATLAB和Octave中的字符串实际上只是一个字符数组,所以下面这个语句实际上是一个三维数组。
[['rock', 'metal']]

如果我们用数字代替字符,使其更清晰地成为一个三维数组,我们会得到类似于这样的东西。
[[[1,2,3], [4,5,6]]]

当你使用savemat将它们中的任何一个保存到.mat文件时,它将被视为3D数组。
如果你想要一个单元格数组,你必须手动创建一个由numpy对象组成的numpy数组。
import scipy
import numpy as np

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

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

然后在MATLAB或Octave中执行以下操作:

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

更新

对于嵌套的单元数组,在每个您想要成为单元数组的级别上,也必须是numpy对象的numpy数组。

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

1
这有效地解决了我在处理单行矩阵时遇到的问题,但是当我需要处理字典键具有可变长度列表作为值时仍然没有成功。我已经编辑了一个带有示例的问题。 - sparaflAsh
@sparaflAsh 请看更新。任何你想要成为单元数组的东西都必须明确地定义为 np.object 数组。 - Suever
能否将字典保存为结构体而不是单元数组?或者这就是Scipy的工作方式? - 3bdalla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接