如何使用Scipy.io.loadmat将Matlab mat文件中的字符串数组加载到Python列表或元组中

时间:2011-01-27 03:52:56

标签: python arrays string matlab mat-file

我是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中的数组对象。我们将非常感谢您的帮助。

2 个答案:

答案 0 :(得分: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']

答案 1 :(得分:2)

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

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

我使用的是较新版本的MATLAB,默认情况下会以HDF5格式保存.mat个文件。 loadmat无法读取HDF5文件,因此&#39; -v7&#39; flag是强制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)数组,其中包含&#39; thank&#39;的字母。也就是说,

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

要获得第一个字母&#39;,您必须执行以下操作:

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

列表理解需要一些人习惯,但它们非常有用。希望这会有所帮助。