行または列のベクトルを行列に「クローン」すると便利な場合があります。クローニングとは、次のような行ベクトルを変換することを意味します
[1,2,3]
マトリックスに
[[1,2,3]
[1,2,3]
[1,2,3]
]
または次のような列ベクトル
[1
2
3
]
に
[[1,1,1]
[2,2,2]
[3,3,3]
]
Matlabまたはオクターブでは、これは非常に簡単に実行できます。
x = [1,2,3]
a = ones(3,1) * x
a =
1 2 3
1 2 3
1 2 3
b = (x') * ones(1,3)
b =
1 1 1
2 2 2
3 3 3
私はnumpyでこれを繰り返したいが、失敗した
In [14]: x = array([1,2,3])
In [14]: ones((3,1)) * x
Out[14]:
array([[ 1., 2., 3.],
[ 1., 2., 3.],
[ 1., 2., 3.]])
# so far so good
In [16]: x.transpose() * ones((1,3))
Out[16]: array([[ 1., 2., 3.]])
# DAMN
# I end up with
In [17]: (ones((3,1)) * x).transpose()
Out[17]:
array([[ 1., 1., 1.],
[ 2., 2., 2.],
[ 3., 3., 3.]])
最初のメソッド(In [16])が機能しなかったのはなぜですか? pythonでこのタスクをよりエレガントな方法で達成する方法はありますか?
エレガントでPythonicな方法は次のとおりです。
>>> array([[1,2,3],]*3)
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
>>> array([[1,2,3],]*3).transpose()
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3]])
[16]
の問題は、転置が配列に効果がないことのようです。代わりにおそらくマトリックスが必要です:
>>> x = array([1,2,3])
>>> x
array([1, 2, 3])
>>> x.transpose()
array([1, 2, 3])
>>> matrix([1,2,3])
matrix([[1, 2, 3]])
>>> matrix([1,2,3]).transpose()
matrix([[1],
[2],
[3]])
numpy.tile
を使用します。
>>> tile(array([1,2,3]), (3, 1))
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
または繰り返し列の場合:
>>> tile(array([[1,2,3]]).transpose(), (1, 3))
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3]])
最初に、numpyのbroadcasting操作では、通常、行と列を複製する必要がないことに注意してください。説明については、 this および this を参照してください。
しかし、これを行うには、 repeat および newaxis はおそらく最良の方法です
In [12]: x = array([1,2,3])
In [13]: repeat(x[:,newaxis], 3, 1)
Out[13]:
array([[1, 1, 1],
[2, 2, 2],
[3, 3, 3]])
In [14]: repeat(x[newaxis,:], 3, 0)
Out[14]:
array([[1, 2, 3],
[1, 2, 3],
[1, 2, 3]])
この例は行ベクトル用ですが、列ベクトルにこれを適用することは明白です。繰り返しはこれをうまく綴っているようですが、あなたの例のように乗算によってそれを行うこともできます
In [15]: x = array([[1, 2, 3]]) # note the double brackets
In [16]: (ones((3,1))*x).transpose()
Out[16]:
array([[ 1., 1., 1.],
[ 2., 2., 2.],
[ 3., 3., 3.]])
Numpyでブロードキャストを使用するのが最良で、より高速だと思います
私は次のように比較しました
import numpy as np
b = np.random.randn(1000)
In [105]: %timeit c = np.tile(b[:, newaxis], (1,100))
1000 loops, best of 3: 354 µs per loop
In [106]: %timeit c = np.repeat(b[:, newaxis], 100, axis=1)
1000 loops, best of 3: 347 µs per loop
In [107]: %timeit c = np.array([b,]*100).transpose()
100 loops, best of 3: 5.56 ms per loop
ブロードキャストを使用すると約15倍高速
np.broadcast_to
はnp.tile
よりも高速です:
x = np.arange(9)
%timeit np.broadcast_to(x, (6,9))
100000 loops, best of 3: 3.6 µs per loop
%timeit np.tile(x, (6,1))
100000 loops, best of 3: 8.4 µs per loop
しかし、最速は@ tom10の方法です:
%timeit np.repeat(x[np.newaxis, :], 6, axis=0)
100000 loops, best of 3: 3.15 µs per loop
使用できます
np.tile(x,3).reshape((4,3))
タイルはベクターの担当者を生成します
形状を変更すると、希望する形状になります
1つのクリーンなソリューションは、NumPyの外積関数を1のベクトルで使用することです。
np.outer(np.ones(n), x)
n
繰り返し行を提供します。引数の順序を切り替えて、繰り返し列を取得します。同じ数の行と列を取得するには
np.outer(np.ones_like(x), x)
import numpy as np
x=np.array([1,2,3])
y=np.multiply(np.ones((len(x),len(x))),x).T
print(y)
収量:
[[ 1. 1. 1.]
[ 2. 2. 2.]
[ 3. 3. 3.]]