6

我是 Python 新手的 Matlab 用户。我想将 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 中的数组对象。您的帮助将不胜感激。

4

2 回答 2

5

你试过这个:

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']
于 2011-01-27T08:03:21.290 回答
2

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

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

我正在使用较新版本的 MATLAB,它.mat默认以 HDF5 格式保存文件。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) 数组,其中包含“thank”的字母。那是,

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']

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

于 2014-09-09T21:56:13.377 回答