【问题标题】:Saving dictionaries from Python to Matlab with Scipy使用 Scipy 将字典从 Python 保存到 Matlab
【发布时间】:2017-06-01 07:32:45
【问题描述】:

我发现将我生成的整洁数据保存到 .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 中看到的:

到底发生了什么?有解决办法吗?

【问题讨论】:

    标签: python matlab scipy cell-array


    【解决方案1】:

    问题是MATLAB和Octave中的字符串实际上只是一个字符数组,所以下面的语句实际上是一个3D数组

    [['rock', 'metal']]
    

    如果我们用数字替换字符以使其更清楚地表明它是一个 3D 数组,我们会得到类似这样的结果

    [[[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)}
    

    【讨论】:

    • 这有效地解决了我使用单行矩阵时遇到的问题,但是当我必须处理具有可变长度列表作为值的字典键时仍然没有成功。我已经用一个例子编辑了这个问题。
    • @sparaflAsh 查看更新。任何想要成为元胞数组的东西都必须明确定义为 np.object 数组
    • 是否可以将字典保存为结构而不是元胞数组?或者这就是 scipy 的工作原理?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 2015-04-16
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    相关资源
    最近更新 更多