2

SciPyとMATLABを使用して、scipy.io.loadmat()を使用してロードされたMATLABセル配列から与えられたものと一致するように配列を再構築するのに問題があります。

たとえば、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,1,4)ではなく(2、)の形をしているのですか?実生活では、Pythonを使用してログファイルを解析し、これらの開始セル配列を構築しようとしているので、最初から構築できるようにしたいと考えています。

印刷された出力から同じ配列を作成しようとすると、異なる形状が返されます。

>>> 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)

残念ながら、形状(セル配列内のdoubleのベクトル)はアップストリームの仕様でコード化されているため、これをこの形式で正確に保存できるようにする必要があります。もちろん、MATLABでパーサーを書くことができたので、大したことではありませんが、何が起こっているのかを理解し、numpyに関する私の[小さな]知識に少し追加するとよいでしょう。

4

3 に答える 3

1

これは、私が個人的にPythonでやっかいなことの1つです。これは、loadmat寸法を自動的に「圧迫」するためです。

デフォルトでは、squeeze_me = Trueであるため、次のようになります。

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

squeeze_meをFalseに設定してloadmatを使用する場合、1つのディメンションが絞り出されません。

>>> 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}];
于 2012-05-10T22:51:21.033 に答える
1

ここでの問題は、セル配列が実際には配列ではないことだと思います。そのため、配列にscio.loadmatロードされます。onsets.matobject

ここでは、セル配列を通常の形状の配列に縮小できますが(2,1,4)、代わりに、データが次のようになっている場合はどうでしょうか。

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

最善の解決策はわかりませんが、データが配列であることがわかっている場合は、Matlabに保存する前、またはScipyでロードした後に、通常の配列に変換する必要があります。

編集:上記のセル配列の例は、理論的には、numpy構造の配列にキャストできますが、列が同じデータ型である必要はないため、セル配列には一般的に当てはまらないことに注意してください。任意のデータ型のリストを表す論理的な方法は、Pythonリスト(またはここではリストの配列)を使用することです。これがloadmat返されます。

編集2: Erik Kastmanが提案したように、セル配列の構文を修正します。

于 2012-05-11T15:42:52.750 に答える
1

scipyメーリングリストのTravisは、これを構築する正しい方法は、最初に構造を作成してから、配列にデータを入力することであると回答しました。

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

>以前に見たものを次のように構築できます:
>>
> new_onsets = empty((2、)、dtype = object)
> new_onsets [0] = array([[0、30、60、90]])
> new_onsets [1] = array([[15、45、75、105]])
于 2012-05-14T15:44:45.540 に答える