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]]]