Matlab to python: получить значения массива ячеек Matlab

Я очень новичок в Matlab и Python, и мне нужно использовать некоторые значения в python из массива ячеек Matlab.

У меня есть массив ячеек целых чисел, который после того, как я выполню эту строку кода и распечатаю результат, я получаю следующее:

a = loadmat('file.mat')
print a

{'__version__': '1.0', '__header__': 'MATLAB 5.0 MAT-file, Platform: PCWIN, Created on: Wed Sep 21 15:30:15 2011', 'juncForward_c': array([[ [[ [[ ([[30]], **[[91], [87]]**, [[3]], [[2.2455372690184494, 3.6052402625905993, 5.5884470309828833]], [[14.0, 4.0, 15.4]], [[-1, -1, 2]], [[91, 89, 93], [88, 85, 86]], [[500, 500, 5]], [[1, 2, 3]], [[11.133333333333333]], **[[4]]**, [[1]], [[1]], [[1.0], [20.365168528421695]])]]

[[ ([[30]], **[[99], [80]]**, [[3]], [[4.0376480381611373, 2.3561944901923448, 6.0857897473297058]], [[10.0, 15.4, 16.600000000000001]], [[-1, 1, 3]], [[98, 98, 100], [79, 81, 80]], [[500, 6, 33]], [[1, 2, 3]], **[[14]]**, [[2]], [[1]], [[1]], [[2.0], [6.6573267908372973]])]]

и печать продолжается.

Может ли кто-нибудь объяснить мне, как устроен массив ячеек? (так сколько измерений выше?)

Затем у меня есть несколько вопросов: 1) В этом массиве ячеек есть переменные «метка» и «координаты», которые назначаются одному массиву/ячейке (я не знаю, какой термин использовать) — значения выделены жирным шрифтом . Я хотел бы написать на Python, чтобы получить доступ к этим значениям. Как мне это сделать?

2) Для проверки я попробовал это -> juncInfoF = a.get('juncForward_c'), и когда я пытаюсь напечатать juncInfoF, он печатает «Нет». Почему это так? Я озадачен, потому что раньше, когда я пробовал это, это работало. Я мог бы даже сделать это -> print juncInfo[0][9][0][0]. но теперь я не могу сделать даже ничего из вышеперечисленного.


person user974666    schedule 01.10.2011    source источник


Ответы (2)


Я предполагаю, что loadmat('file.mat') возвращает экземпляр класса shelve, унаследованного от класса dict. . Я предполагаю, что вы используете функцию loadmat из scipy.io?

from scipy.io import loadmat

В документе scipy упоминаются только возвраты loadmat() словарь, но я предполагаю, что возвращенный объект a в вашем примере является открытым файлом полки, и вы больше не можете получить доступ к его содержимому, когда a является closed, что может произойти по нескольким причинам, помимо ручного вызова a.close().

Чтобы этого не произошло, сначала скопируйте все данные в настоящий словарь, а затем загрузите эти данные:

mat_dict = {}
mat_dict.update(loadmat('file.mat'))

Теперь вы можете получить все ключи и значения из mat_dict:

a = mat_dict['juncForward_c']
print(a.shape) # should work now

обратите внимание, что это допустимое решение, если вы тестируете и выясняете, что представляют собой данные mat_dict. В вашем скрипте/модели/функции вы обычно загружаете только ту часть полки, которую хотите, а затем явно закрываете файл:

f = loadmat('file.mat')
a = f['juncForward_c']
f.close()

Я не знаю, работает ли оператор with (полка его пока не поддерживает), вам придется протестировать его, но он должен обрабатывать закрытие, даже если во время загрузки a возникает исключение:

with loadmat('file.mat') as f:
    a = f['juncForward_c']

edit: подкласс из массива numpy для добавления дополнительных атрибутов

import numpy as np

class MatArray(np.array):
    def __init__(self, filepath):
        f = loadmat(filepath)
        np.array.__init__(self, f['juncForward_c'])
        self.version = f['__version__']
        self.header = f['__header__']
        f.close() 

так что теперь, если вы хотите, чтобы ваш массив напоминал структуру Matlab, вы делаете:

>>> a = MatArray('myfile.mat')
>>> a.header
'MATLAB 5.0 MAT-file, Platform: PCWIN, Created on: Wed Sep 21 15:30:15 2011'
>>> a.shape

так далее

person Remi    schedule 01.10.2011
comment
привет Реми! Большое спасибо за ваш ответ! Я также хотел бы спросить, есть ли способ, которым словарь сохранил бы исходные структуры, хранящиеся в матовом файле. потому что, по словам человека, который закодировал матфайл, она сказала мне, что значения в матфайле хранятся в соответствии с определенными структурами. следовательно, можно использовать a.label для получения значения метки. могу ли я сделать это с помощью python после того, как я загрузил данные файла .mat в python, используя ваш метод выше? потому что я на самом деле пытался ввести a.label, но это не позволяет мне это сделать. - person user974666; 03.10.2011
comment
вы можете создать свой собственный класс и присвоить значения его атрибутов в соответствии с ключами в загруженном словаре. Вы пытались помочь (loadmat)? кажется, ключевое слово struct_as_record может быть вам интересно. В противном случае опубликуйте пример вашего файла .mat. - person Remi; 03.10.2011
comment
ключи словаря возвращаются, когда я использую scipy.io.loadmat('file.mat'): ('версия','1.0'), ('header',' MATLAB 5.0....'), ('juncForward_c', array([[ [[ [[ ([[30.0]],[[91.0],[87.0]],[[3.0]],[[2.2454534533.785785 ,5.4354]], ... )]] и т. д.) dtype = object)), так как же мне получить атрибуты в ndarray, возвращаемые как значение ключа: juncForward_c? может быть, я не могу загрузить файл .mat таким образом? - person user974666; 04.10.2011
comment
Вы говорите, что хотите, чтобы другие ключи были дополнительными атрибутами в вашем массиве numpy? Вы можете создать подкласс из numpy arry и сделать что-то вроде моего редактора выше. - person Remi; 04.10.2011
comment
окай я понял! большое спасибо за ваше время Реми. мне пришлось сделать это: a = f['juncForward_c'][0,0][0,0]['label']. знак равно - person user974666; 05.10.2011
comment
Таким образом, метка была не атрибутом, а ключом к содержимому ячейки (элемента массива) внутри ячейки; трудно догадаться без исходного файла ... В stackoverflow вы можете выразить свою признательность, проголосовав и приняв ответы (подсказка;)) - person Remi; 05.10.2011

Если в вашем мат-файле есть только массивы ячеек со списком целых чисел или строк, я написал для этого общий код. Например, в матлабе можно сделать что-то вроде этого:

names = cell(1, N);
indices = cell(1, N);
for ind=1:N
    names{ind} = *some_value*;
    indices{ind} = *some_array*;
save('names_and_indices.mat', 'names', 'indices');

Здесь вы можете узнать, как читать этот матовый файл в python.

person Noam Peled    schedule 18.02.2016