web-dev-qa-db-ja.com

「クローン」行または列ベクトル

行または列のベクトルを行列に「クローン」すると便利な場合があります。クローニングとは、次のような行ベクトルを変換することを意味します

[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でこのタスクをよりエレガントな方法で達成する方法はありますか?

127
Boris Gorelik

エレガントで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]])
64
Peter

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]])
249
pv.

最初に、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.]])
33
tom10

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倍高速

8
smartkevin

np.broadcast_tonp.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
6
Mateen Ulhaq

使用できます

np.tile(x,3).reshape((4,3))

タイルはベクターの担当者を生成します

形状を変更すると、希望する形状になります

2
thebeancounter

1つのクリーンなソリューションは、NumPyの外積関数を1のベクトルで使用することです。

np.outer(np.ones(n), x)

n繰り返し行を提供します。引数の順序を切り替えて、繰り返し列を取得します。同じ数の行と列を取得するには

np.outer(np.ones_like(x), x)
2
Jon Deaton
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.]]
0
kibitzforu