【问题标题】:How to load cell array of strings in Matlab mat files into Python list or tuple using Scipy.io.loadmat如何使用 Scipy.io.loadmat 将 Matlab mat 文件中的字符串单元格数组加载到 Python 列表或元组中
【发布时间】:2011-06-16 07:13:58
【问题描述】:

我是一个 Matlab 用户,不熟悉 Python。我想将 Matlab 中的字符串单元数组写入 Mat 文件,并使用 Python(可能是 scipy.io.loadmat)将此 Mat 文件加载到一些类似的类型(例如字符串列表或字符串元组)中。但是 loadmat 将内容读入数组,我不确定如何将其转换为列表。我尝试了无法按预期工作的“tolist”函数(我对 Python 数组或 numpy 数组了解甚少)。例如:

Matlab 代码:

cell_of_strings = {'thank',  'you', 'very', 'much'};
save('my.mat', 'cell_of_strings');

Python 代码:

matdata=loadmat('my.mat', chars_as_strings=1, matlab_compatible=1);
array_of_strings = matdata['cell_of_strings']

那么,变量array_of_strings就是:

array([[[[u't' u'h' u'a' u'n' u'k']], [[u'y' u'o' u'u']],
    [[u'v' u'e' u'r' u'y']], [[u'm' u'u' u'c' u'h']]]], dtype=object)

我不知道如何将此 array_of_strings 转换为 Python 列表或元组,使其看起来像

list_of_strings = ['thank',  'you', 'very', 'much'];

我不熟悉 Python 或 numpy 中的数组对象。您的帮助将不胜感激。

【问题讨论】:

    标签: python arrays string matlab mat-file


    【解决方案1】:

    你试过了吗:

    import scipy.io as si
    
    a = si.loadmat('my.mat')
    b = a['cell_of_strings']                # type(b) <type 'numpy.ndarray'>
    list_of_strings  = b.tolist()           # type(list_of_strings ) <type 'list'>
    
    print list_of_strings 
    # output: [u'thank', u'you', u'very', u'much']
    

    【讨论】:

    • b.tolist() 给出 [[array([[u't', u'h', u'a', u'n', u'k']], dtype='
    • @Denzel。是否必须使用 chars_as_strings=1, matlab_compatible=1?
    【解决方案2】:

    这看起来像是list comprehension 的工作。重复你的例子,我在 MATLAB 中做了这个:

    cell_of_strings = {'thank',  'you', 'very', 'much'};
    save('my.mat', 'cell_of_strings','-v7'); 
    

    我使用的是较新版本的 MATLAB,它默认以 HDF5 格式保存 .mat 文件。 loadmat 无法读取 HDF5 文件,所以 '-v7' 标志是强制 MATLAB 保存到旧版本的 .mat 文件,loadmat 可以理解。

    在 Python 中,我像您一样加载了元胞数组:

    import scipy.io as sio
    matdata = sio.loadmat('%s/my.mat' %path, chars_as_strings=1, matlab_compatible=1);  
    array_of_strings = matdata['cell_of_strings']
    

    打印array_of_strings 给出:

    [[array([[u't', u'h', u'a', u'n', u'k']], 
              dtype='<U1')
          array([[u'y', u'o', u'u']], 
              dtype='<U1')
          array([[u'v', u'e', u'r', u'y']], 
              dtype='<U1')
          array([[u'm', u'u', u'c', u'h']], 
              dtype='<U1')]]
    

    变量array_of_strings 是一个 (1,4) numpy 对象数组,但每个对象中都嵌套了数组。例如,array_of_strings 的第一个元素是一个 (1,5) 数组,其中包含表示“谢谢”的字母。也就是说,

    array_of_strings[0,0]
    array([[u't', u'h', u'a', u'n', u'k']], 
          dtype='<U1')
    

    要获得第一个字母“t”,您必须执行以下操作:

    array_of_strings[0,0][0,0]
    u't'
    

    由于我们正在处理嵌套数组,我们需要使用一些递归技术来提取数据,即嵌套for 循环。但首先,我将向您展示如何提取第一个单词:

    first_word = [str(''.join(letter)) for letter in array_of_strings[0][0]]
    first_word
    ['thank']
    

    我在这里使用列表推导。基本上,我正在遍历 array_of_strings[0][0] 中的每个字母,并使用''.join 方法将它们连接起来。 string() 函数是将 unicode 字符串转换为常规字符串。

    现在,为了得到你想要的列表字符串,我们只需要遍历每个字母数组:

    words = [str(''.join(letter)) for letter_array in array_of_strings[0] for letter in letter_array]
    words
    ['thank', 'you', 'very', 'much']
    

    列表推导式需要一些时间来适应,但它们非常有用。希望这会有所帮助。

    【讨论】:

    • words = [str(''.join(letter)) for letter_array in array_of_strings[0] for letter in letter_array] 应该是 words = [str(''.join(letter)) for letter_array在 array_of_strings 中为 letter_array 中的字母]
    猜你喜欢
    • 2017-12-27
    • 2018-04-28
    • 2011-11-19
    • 2011-09-10
    • 2014-04-14
    • 1970-01-01
    • 2012-10-02
    • 1970-01-01
    • 2014-11-09
    相关资源
    最近更新 更多