2016-10-26 12 views
3

私はいくつかのMATLABコードをnumpy配列経由でPythonに変換するには不運です。num2cell()のpython/numpyに相当するのは何ですか?

num2cell()にはコンセンサスがありますか?

個人的には、これはPython/numpyの構文に反すると思います。アイデアはこれです:

num2cellを使用して、あなたが見るthe MathWorks documentaitonこの

array([[0],[1],[2],[3],[4],[5],[6],[7],[8]])

のように見えるの配列になってしまいます。

あなたはリスト内包とnumpyの中でこれを行うことができます:

matlab_lunacy = np.array([[x] for x in range(0, 9)] 

しかし、なぜ、MATLABユーザーはこのデータ構造を使用していますか?

numpyに相当するものは何ですか?

+0

'num2cell()'はデータの分割に非常に便利です。マルチDアレイをセクションに簡単にスライスすることができ、後続の操作が容易になります。行のリスト、列のリストなど、または任意のブロックのリストを持つように、スライスすることができます。 –

+6

MATLABのセルは通常、非規則的な(行列以外の)データ構造に使用されます。サイズの異なるベクトルのシーケンスまたは文字列のシーケンス。 Pythonの同等の機能は、オブジェクトのネイティブリスト(または辞書)です。 –

+1

私たちの回答はどんな役に立ちましたか? – rayryeng

答えて

4

古き良き時代(約3.0節)には、MATLABには1つのデータ構造、つまり行列がありました。数字や文字を含むことができ、常に2dだった。

マトリックスや文字列を含むより一般的なオブジェクトを含むようにセルが追加されました。彼らはまだ2dだった。

Pythonはリストを持っていましたが、リストは1dですが、何でも含めることができます。 numpyはPython上に構築され、多次元配列を追加します。しかしリストはまだ利用可能です。

配列をリストに変換する可能性のあるものは、num2cellと同じですが、機能は重複していますが、正確ではありません。

In [247]: B=list(A) 
In [248]: B 
Out[248]: 
[array([[ 0, 1, 2, 3], 
     [ 4, 5, 6, 7], 
     [ 8, 9, 10, 11]]), 
array([[12, 13, 14, 15], 
     [16, 17, 18, 19], 
     [20, 21, 22, 23]])] 

tolist方法は、リスト(ネストされた)への完全な変換を実行します。リスト内

In [246]: A=np.arange(24).reshape(2,3,4) # 3d array 

ラッピングは、米国2つのアレイ(2D)のリストを与えます。

In [249]: C=A.tolist() 
In [250]: C 
Out[250]: 
[[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], 
[[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]] 

list(A)一般的ではなく、tolistを意味している際にエラーに使用することができます。

np.split(A,...)Bと似ていますが、サブアレイはまだ3dです。 Aは反復可能であるため、[a for a in A]は1次元目にAを分割します。Aは繰り返し可能ですので、Aは反復可能ですので、Aが繰り返し可能です。

In [257]: a,b=A 
In [258]: a 
Out[258]: 
array([[ 0, 1, 2, 3], 
     [ 4, 5, 6, 7], 
     [ 8, 9, 10, 11]]) 

dtypeというオブジェクトがあります。これにより、他の配列を含むオブジェクトを配列に配置できます。しかし、多くのSOの質問に示されているように、これは構築するのが難しいかもしれません。 np.arrayは可能な限り最高次元の配列を作成しようとします。あなたはそれを回避するためにいくつかのトリックを実行する必要があります。

In [259]: Z=np.empty((2,),dtype=object) 
In [260]: Z 
Out[260]: array([None, None], dtype=object) 
In [261]: Z[0]=A[0] 
In [262]: Z[1]=A[1] 
In [263]: Z 
Out[263]: 
array([ array([[ 0, 1, 2, 3], 
     [ 4, 5, 6, 7], 
     [ 8, 9, 10, 11]]), 
     array([[12, 13, 14, 15], 
     [16, 17, 18, 19], 
     [20, 21, 22, 23]])], dtype=object) 

================オクターブセッションにおいて

>> anum = [1,2,3,4] 
anum = 

    1 2 3 4 

>> acell = num2cell(anum) 
acell = 
{ 
    [1,1] = 1 
    [1,2] = 2 
    [1,3] = 3 
    [1,4] = 4 
} 
>> save -7 test.mat anum acell 

scipy.io.loatmatバージョン

In [1822]: data = io.loadmat('../test.mat') 
In [1823]: data 
Out[1823]: 
{'__globals__': [], 
'__header__': b'MATLAB 5.0 MAT-file, written by Octave 4.0.0, 
    2016-10-27 00:59:27 UTC', 
'__version__': '1.0', 
'acell': array([[array([[ 1.]]), array([[ 2.]]), array([[ 3.]]), 
     array([[ 4.]])]], dtype=object), 
'anum': array([[ 1., 2., 3., 4.]])} 

matrixは2次元配列としてレンダリングされます。オブジェクトタイプ配列(2d)としてcellを含み、この場合、2次元配列を含む。

+0

ニース。私は 'tolist'が存在するのか知らなかった。私の再帰的な実装を打ち負かす。 – rayryeng

1

コードの残りの部分によって異なります。一般的に言えば、Matlabはセルを使用して配列の配列を表します。ここで、内部配列は異なるサイズと形状を持つことができます。

あなたの質問に答えるには、基本的にあなたがやりたいこと、つまり配列の配列を作成することだと思います。

2

num2cellは、基本的にアレイの各要素を取り、それをセルマトリックス内の個別のセルとして表示します。セル配列に相当するPythonはリストです。したがって、Pythonでnum2cell相当のものを作成したい場合は、Python NumPy配列と同じ次元のリストを作成し、このリストの各要素が適切な場所に配置されるようにします。このような何かに動作します:

import numpy as np 

def num2cell(a): 
    if type(a) is np.ndarray: 
     return [num2cell(x) for x in a] 
    else: 
     return a   

この再帰的は、あなたのnumpyの配列の各次元を通過します。この配列の次元の各要素について、その要素が配列でもある場合、次の次元の各要素について、リスト表現に変換します。基本ケースは、実際に実際の数値に当たったときです。その場合、実際の数値を返します。

ここに私のPythonワークスペースでnum2cellを定義した後の作業例を示します

In [26]: import numpy as np 

In [27]: A = np.random.rand(4,3,3) 

In [28]: B = num2cell(A) 

In [29]: A[0] 
Out[29]: 
array([[ 0.52971132, 0.91969837, 0.77649566], 
     [ 0.51080951, 0.8086879 , 0.61840573], 
     [ 0.7291165 , 0.0492292 , 0.53997368]]) 

In [30]: B[0] 
Out[30]: 
[[0.52971132352406691, 0.91969837282865874, 0.77649565991300817], 
[0.51080951338602765, 0.80868789862631529, 0.61840573261134801], 
[0.72911649507775378, 0.049229201932639577, 0.53997367763478676]] 

In [31]: A[1][1] 
Out[31]: array([ 0.41724412, 0.94679946, 0.79899245]) 

In [32]: B[1][1] 
Out[32]: [0.41724411973558406, 0.9467994633124529, 0.7989924496851234] 

我々はBがnumpyの配列Aのリスト表現であることをここで見ることができます。

+0

'A.tolist()'は 'num2cell(A)'とほとんど同じ結果を返しますが、唯一の違いは 'np.float64'ではなく各要素がネイティブのPython' float'になることです。 –

+0

@ali_mわかりました。私はhpauljの投稿にコメントを残しました。基本的には、 'tolist()'が存在することを知らなかったと言います。 – rayryeng

+0

@ali_mまったくありません。私はおそらくそれを反映するために私の投稿を編集する必要があります。私はあなたのコメントを感謝します。 – rayryeng

1

.astype(np.object_)が最も必要なものです。 numpyので

x = [1 2 3 4] 
y = num2cell(x) 
y(end) = 'hello' 

に変換します:

x = np.array([1, 2, 3, 4]) 
y = x.astype(np.object_) 
y[-1] = 'hello' 
-2

取るために完全に異なるルートはあなたがまた、これにより、MATLABエンジンを呼び出すとすることを可能にするmatlabs Pythonインタフェースを使用することです。このMathWorks社のMATLABコードを考えてみましょうPythonのMATLABコードhttps://se.mathworks.com/help/matlab/matlab-engine-for-python.html

+1

これは毛むくじゃらのようです... – ShanZhengYang

+0

ライブラリを互いにリンクする必要があるので、セットアップはかなり毛深いですが、ガイドはかなりよく書かれています。一旦それをインストールすると、 'import matlab.engine'をインポートして' eng = matlab.engine.start_matlab() 'と定義するだけで簡単になり、今では独自のMATLAB関数を呼び出すことができます。 'result = eng.YourFunction(inputs) ' –

+2

このインターフェイスは、MATLABとPythonの間で通信するように設計されているため、有効なMATLABライセンスとMATLABサーバーがまだ開始されています。通常、コードは移植される。あなたがMATLABライセンスのためのお金を持っていないとき。お持ちの場合は、元のコードを実行するだけです。 –

関連する問題