Как загрузить массив ячеек строк в файлах Matlab Mat в список или кортеж Python, используя Scipy.io.loadmat - PullRequest
6 голосов
/ 27 января 2011

Я пользователь Matlab, плохо знакомый с Python. Я хотел бы записать массив ячеек строк в Matlab в файл Mat и загрузить этот файл Mat, используя Python (возможно, scipy.io.loadmat), в некоторый аналогичный тип (например, список строк или кортеж строк). Но 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 ]

5 голосов
/ 27 января 2011

Вы пробовали это:

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']
2 голосов
/ 10 сентября 2014

Это похоже на работу для понимания списка .Повторяя ваш пример, я сделал это в 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) массив пустых объектов, но есть массивы, вложенные в каждый объект.Например, первый элемент 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() предназначена для преобразования строк Юникода в обычные строки.

Теперь, чтобы получить нужные вам строки списка, нам просто нужно пройтись по каждому массиву букв:

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

Понимания списка требуют некоторого привыкания, но они чрезвычайно полезны.Надеюсь, это поможет.

...