NumPyを使用して、次のMATLABコードに相当するものを実行したいと思います:repmat([1; 1], [1 1 1])
。どうすればこれを達成できますか?
ここにはるかに優れた(公式) Matlabユーザー向けのNumPy リンク-マテサウルスの1つがかなり古くなっているのではないかと思います。
repmat(a, m, n)
に相当するnumpyは、 tile(a, (m, n))
です。
これは複数の次元で機能し、matlabと同様の結果をもたらします。 (Numpyは予想どおり3D出力配列を提供します-何らかの理由でmatlabは2D出力を提供します-内容は同じです)。
Matlab:
>> repmat([1;1],[1,1,1])
ans =
1
1
Python:
In [46]: a = np.array([[1],[1]])
In [47]: np.tile(a, [1,1,1])
Out[47]:
array([[[1],
[1]]])
MATLABのrepmatを使用する必要がある理由のいくつかは、NumPyの broadcasting メカニズムによって処理されることに注意してください。したがって、たとえば、3色画像を表す1600x1400x3の配列がある場合、(要素単位で)[1.0 0.25 0.25]
を乗算して、各ピクセルの緑と青の量を減らすことができます。詳細については、上記のリンクを参照してください。
tile
とrepeat
の両方を知っています。
x = numpy.arange(5)
print numpy.tile(x, 2)
print x.repeat(2)
これは、少しいじってから理解した方法です。修正されることを嬉しく思い、これが役立つことを願っています。
マトリックスがあるとします[〜#〜] m [〜#〜] 2x3要素。これには明らかに2つの次元があります。
MatlabとPythonの間に違いは見られませんでしたが、マトリックスが既に持っている次元に沿って入力マトリックスを操作するように求めました。したがって、2つのコマンド
_repmat(M,m,n) % matlab
np.tile(M,(m,n)) # python
_
ランク2の行列(2次元)で実際に同等です。
入力行列よりも多くの次元で繰り返し/並べて表示するように要求すると、問題は直観に反します。ランク2および形状2x3のマトリックスMに戻って、出力マトリックスのサイズ/形状がどうなるかを調べるだけで十分です。操作のシーケンスが1,1,2になったとします。
Matlabで
_> size(repmat(M,1,1,2))
ans =
2 3 2
_
入力行列の最初の2つの次元(行と列)をコピーし、それを新しい3番目の次元に1回繰り返しました(つまり、2回コピーしました)。繰り返し行列の命名repmat
に忠実です。
Pythonで
_>>> np.tile(M,(1,1,2)).shape
(1, 2, 6)
_
シーケンス(1,1,2)はMatlabとは異なる方法で読み取られるため、別の手順を適用しています。列、行、および面外寸法の方向のコピー数は、右から左に読み取られます。結果のオブジェクトは、Matlabとは異なる形状になります。 repmat
とtile
が同等の命令であると断言することはできなくなりました。
tile
をrepmat
のように振る舞わせるには、Pythonで、入力行列が要素の数と同じ次元を持っていることを確認する必要がありますこれは、たとえば、少し事前調整して関連オブジェクトを作成することで行われます[〜#〜] n [〜#〜]
_N = M[:,:,np.newaxis]
_
次に、入力側にはN.shape = (2,3,1)
ではなくM.shape = (2,3)
があり、出力側には
_>>> np.tile(N,(1,1,2)).shape
(2, 3, 2)
_
size(repmat(M,1,1,2))
の答えでした。これは、Pythonが、左ではなく(2,3)の右に3番目の次元を追加するように誘導したため、Python Matlabの読み取り方法で意図したとおりにシーケンス(1,1,2)を作成します。
Python [〜#〜] n [〜#〜]の回答の_[:,:,0]
_の要素には、要素_(:,:,1)
_ [〜#〜] m [〜#〜]に対するMatlabの回答。
最後に、Kronecker製品を使用してrepmat
に相当するものを見つけることができないようです。
_>>> np.kron(np.ones((1,1,2)),M).shape
(1, 2, 6)
_
上記のように[〜#〜] m [〜#〜]を[〜#〜] n [〜#〜]に事前調整しない限り、したがって、最も一般的な方法は、_np.newaxis
_の方法を使用することです。
マトリックス[〜#〜] l [〜#〜]ランク3(3次元)および出力マトリックスに新しい次元が追加されないという単純なケースを考慮すると、ゲームは複雑になります。これらの2つの一見同等の命令は、同じ結果を生成しません
_repmat(L,p,q,r) % matlab
np.tile(L,(p,q,r)) # python
_
なぜなら、行、列、面外方向はMatlabでは(p、q、r)であり、Pythonでは(q、r、p)であり、ランク2配列では見えなかったためです。そこで注意する必要があり、2つの言語で同じ結果を得るには、より多くの前提条件が必要です。
この推論は一般的ではないかもしれないことは承知していますが、ここまでしか解決できませんでした。うまくいけば、これは他のフェローにそれをより厳しいテストに誘う。
numpy.matlibには、matlab関数と同様のインターフェイスを持つ repmat 関数があります
from numpy.matlib import repmat
repmat( np.array([[1],[1]]) , 1, 1)
import numpy as np
np.repeat(['a','b'], [2,5])
>>> array(['a', 'a', 'b', 'b', 'b', 'b', 'b'], dtype='<U1')
np.repeat([1,2], [2,5])
>>> array([1, 1, 2, 2, 2, 2, 2])
np.repeat(np.array([1,2]), [3]).reshape(2,3)
>>> array([[1, 1, 1],
[2, 2, 2]])
np.repeat(np.array([1,2]), [2,4]).reshape(3,2)
>>> array([[1, 1],
[2, 2],
[2, 2]])
np.repeat(np.matrix('1 2; 3 4'), [2]).reshape(4,2)
>>> matrix([[1, 1],
[2, 2],
[3, 3],
[4, 4]])