2012-05-10 1 views
2

Использование SciPy и MATLAB, мне трудно восстановить массив, чтобы он соответствовал тому, что задается из массива ячеек MATLAB, загружаемого с помощью scipy.io.loadmat().ndim в массиве numpy, загруженном scipy.io.loadmat?

Например, скажем, создать ячейку, содержащую пару двойных массивов в MATLAB, а затем загрузить его с помощью scipy.io (я использую SPM сделать томографию анализа в сочетании с pynifti и т.п.)

MATLAB

>> onsets{1} = [0 30 60 90] 
>> onsets{2} = [15 45 75 105] 

Python

>>> import scipy.io as scio 
>>> mat = scio.loadmat('onsets.mat') 
>>> mat['onsets'][0] 
array([[[ 0 30 60 90]], [[ 15 45 75 105]]], dtype=object) 

>>> mat['onsets'][0].shape 

(2,) 

Мой вопрос заключается в следующем: Почему это NumPy массив имеет форму (2,) вместо (2,1,4)? В реальной жизни я пытаюсь использовать Python для синтаксического анализа файла журнала и сборки этих массивов ячеек onsets, поэтому я хотел бы иметь возможность создавать их с нуля.

Когда я пытаюсь построить тот же массив из отпечатка, я получаю другую форму обратно:

>>> new_onsets = array([[[ 0, 30, 60, 90]], [[ 15, 45, 75, 105]]], dtype=object) 
array([[[0, 30, 60, 90]], 

     [[15, 45, 75, 105]]], dtype=object) 

>>> new_onsets.shape 
(2,1,4) 

К сожалению, форма (векторы двойников в массиве ячеек) кодируются в спецификации выше , поэтому мне нужно, чтобы это удалось сохранить именно в этом формате. Конечно, это не имеет большого значения, так как я мог просто написать парсер в MATLAB, но было бы неплохо выяснить, что происходит, и немного добавить к моему [minuscule] знанию numpy.

ответ

1

Travis из SciPy списка рассылки ответил, что правильный путь, чтобы построить это, чтобы создать структуру, а затем заполнить массивы:

http://article.gmane.org/gmane.comp.python.scientific.user/31760

 
> You could build what you saw before with: 
> 
> new_onsets = empty((2,), dtype=object) 
> new_onsets[0] = array([[0, 30, 60, 90]]) 
> new_onsets[1] = array([[15, 45, 75, 105]]) 
+0

Вернулся к этому снова; scipy.io теперь имеет очень полезную ссылку для этого: http://docs.scipy.org/doc/scipy/reference/tutorial/io.html –

1

Это одна из тех вещей, которые я лично нахожу досадными в питоне. Это потому, что loadmat автоматически «сжимает» размеры.

По умолчанию squeeze_me = True, так как вы уже видели вы получите это:

>>> x = sio.loadmat('mymat.mat',squeeze_me=True) 
>>> y = x['onsets'] 
>>> y.shape 
(2,) 

Если вы используете loadmat с squeeze_me значение ЛОЖЬ, то вы не получите один размер выжатой:

>>> a = sio.loadmat('mymat.mat',squeeze_me=False) 
>>> a 
>>> b = a['onsets'] 
>>> b.shape 
(1, 2) 

Это сказало, что я не могу для жизни меня выяснить, как получить другое измерение, чтобы показать (то есть, b.shape = (1,2,4)) для массива ячеек типа «onsets». Я только был в состоянии получить его для не-клеточных набившие оскомины ванили MATLAB массивов

onset_array = [onsets{1}; onsets{2}]; 
+0

Спасибо за быстрый ответ! Я не уверен, что делает squeeze_me, но я все еще получаю (2,) даже с squeeze_me = False. (Может быть, он недостаточно хорошо смотрит в массив ячеек?) Я постараюсь продолжать копать и сообщить, найду ли что-нибудь. (Аналогично, я не уверен, что делает do_compression в savemat, но это не повлияло ни на один из моих тестов. –

+0

Чтобы правильно строить размеры, в scipy-списке говорится, что сначала построить структуру с пустыми() и а затем заполнить его данными. –

+1

'раздражает в python' Нет. Должно быть« раздражающим в ** scipy ** ». Две * очень разные вещи. scipy, numpy, matplotlib (примечание: все * сторонние внешние модули *) совершенно отличный мир. По моему опыту некоторые из них просто игнорируют питоническую философию в пользу своих собственных. Не однозначно к лучшему. – n611x007

1

Я думаю, что проблема здесь в том, что клеточные массивы не являются действительно массивами, поэтому scio.loadmat нагрузки onsets.mat к object массив.

Здесь ваш массив ячеек может быть уменьшена до нормального массива формы (2,1,4), но что, если, вместо этого, ваши данные выглядели как:

>> onsets{1} = {0 30 60 'bob'} 
>> onsets{2} = {15 45 75 'fred'} 

Я не уверен, что лучшее решение, но если вы знаете, что ваши данные являются массивом, вы должны, вероятно, преобразовать в обычный массив перед сохранением в Matlab или после загрузки с помощью Scipy.

Edit: Массив примера ячейки выше, теоретически мог быть брошен в NumPy structured array, но учтите, что это вообще не верно клеточные массивы, поскольку столбцы не должны быть тем же типом данных.Логичным способом представления списков произвольных типов данных является список Python (или массив списков здесь), который возвращает loadmat.

Редактировать 2: Исправить синтаксис массива ячеек, как предложил Эрик Кастман.

+1

Я согласен, что это не очень многовалютно-совместимый формат, но это то, что мне нужно использовать для другого программного пакета, поэтому я заблокирован в нем. Я думаю, вам нужно сделать массивы ячеек в приведенном выше примере, например: {0 30 60 'bob'}, которые будут вложенными массивами ячеек. имеют массивы удваивается, поэтому мне не нужно беспокоиться о суб-ячейках или структурах. –

 Смежные вопросы

  • Нет связанных вопросов^_^