LoginSignup
3
0

More than 3 years have passed since last update.

Pythonで行列の列ごとにr倍したい

Last updated at Posted at 2018-04-21

This post is inspired by "https://stackoverflow.com/questions/36532682/multiplying-numpy-arrays-by-scalars".

2つ, n x dのnumpy行列があって、列ごとにスカラー倍したいときどうするのか。という課題。

以下のように、「行列が2個」となる配列の階層で「サイズが2」のarrayを broadcast すると、問題が解けるらしい。

試しに、1と2だけで出来た行列のうち、2で出来た行列だけを0.5倍してみる。
[1, 0.5]というベクトルを、broadcastして行列にかけることで、片方のベクトルだけ0.5倍したことになる。

>>> A = np.array([np.ones((3,4)), 2*np.ones((3,4))])
>>> b = np.array([1, 0.5])
>>> print(A, A.shape, b[:, None, None].shape)

[[[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[2. 2. 2. 2.]
  [2. 2. 2. 2.]
  [2. 2. 2. 2.]]] (2, 3, 4) (2, 1, 1)
>>> print(A * b[:, None, None])

[[[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]

 [[1. 1. 1. 1.]
  [1. 1. 1. 1.]
  [1. 1. 1. 1.]]]

まだ何やっているのかよく分からず、例えば [2, n, d] x [2, n, 1] はうまく出来るんだろうか。

2019/11/06 追記

Broadcastは、要は片方だけがサイズ1の方向に関しては掛け合わせる行列に合わせてサイズを自動で合わせる方法でした。

NumPyのブロードキャストのメリットと解説 - DeepAge

なので、上述の(2, 3, 4)行列に、例えば(2, 3)行列を(2, 3, 1)に引き伸ばして代入すると、(2,3,1)行列が(2,3,4)行列として自動で引き伸ばされて乗じることになります。
例えばで以下に2x3行列を作って乗じる例を示します。

>>> b=np.array([[1,1,1], [0.33, .5, .66]])
>>> print(A*b[:,:,None])

[[[1.   1.   1.   1.  ]
  [1.   1.   1.   1.  ]
  [1.   1.   1.   1.  ]]

 [[0.66 0.66 0.66 0.66]
  [1.   1.   1.   1.  ]
  [1.32 1.32 1.32 1.32]]]
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0