NumPy

NumPy Quickstart チュートリアルに取り組む (4-2) ブロードキャスト 一般的なルール

2つの配列を操作するとき、NumPyはその形状を要素ごとに比較する。これは、後続の(つまり右端の)次元から始まり、左に移動する。2つの次元は「同等である、それらの中の1つが1」である場合に互換性があります。

2つの条件が満たされない場合は、配列が互換性のない形状であることを示す。ValueError: operands could not be broadcast together 例外がスローされる。結果として得られる配列のサイズは、入力の各軸に沿って1ではないサイズ。

配列は同じ次元数を持つ必要はない。例えば、RGB 値の 256x256x3 の配列があり、画像の各色を異なる値で拡大縮小したい場合は、3 つの値を持つ 1 次元の配列で画像を乗算することができる。これらの配列の後続の軸のサイズをブロードキャストのルールに従って並べると、互換性があることがわかる。

Image  (3d array): 256 x 256 x 3
Scale  (1d array):             3
Result (3d array): 256 x 256 x 3

比較される寸法がどちらか一方の場合、もう一方の寸法が使用される。言い換えれば、サイズが1の場合は、他の寸法と一致するように引き伸ばされるか、または「コピー」される。

ブロードキャストする例
A配列とB配列の両方に長さ1の軸があり、それがブロードキャスト操作の間により大きなサイズに展開されている。
A      (4d array):  8 x 1 x 6 x 1
B      (3d array):      7 x 1 x 5
Result (4d array):  8 x 7 x 6 x 5

その他の例

A      (2d array):  5 x 4
B      (1d array):      1
Result (2d array):  5 x 4

A      (2d array):  5 x 4
B      (1d array):      4
Result (2d array):  5 x 4

A      (3d array):  15 x 3 x 5
B      (3d array):  15 x 1 x 5
Result (3d array):  15 x 3 x 5

A      (3d array):  15 x 3 x 5
B      (2d array):       3 x 5
Result (3d array):  15 x 3 x 5

A      (3d array):  15 x 3 x 5
B      (2d array):       3 x 1
Result (3d array):  15 x 3 x 5


ブロードキャストしない例
最後のサイズが一致しない
A      (1d array):  3
B      (1d array):  4

最後から2番目が不一致
A      (2d array):      2 x 1
B      (3d array):  8 x 4 x 3

ブロードキャストの例

import numpy as np

x = np.arange(4)
xx = x.reshape(4,1)
y = np.ones(5)
z = np.ones((3,4))

print(x.shape)  # (4,)
print(y.shape)  # (5,)
# print(x + y)
# ValueError: operands could not be broadcast together with shapes (4,) (5,) 
    
print(xx.shape)  # (4, 1)
print(y.shape)  # (5,)
print((xx + y).shape)  # (4, 5)
print(xx + y)
'''
[[1. 1. 1. 1. 1.]
 [2. 2. 2. 2. 2.]
 [3. 3. 3. 3. 3.]
 [4. 4. 4. 4. 4.]]
'''
print(x.shape)  # (4,)
print(z.shape)  # (3, 4)
print((x + z).shape)  # (3, 4)
print(x + z)
'''
[[1. 2. 3. 4.]
 [1. 2. 3. 4.]
 [1. 2. 3. 4.]]
'''

2つの配列の外積(または他の任意の外積演算)を取る便利な方法を提供する。次の例で2つの1次元配列の外部加算演算を示す。

import numpy as np

a = np.array([0.0, 10.0, 20.0, 30.0])
b = np.array([1.0, 2.0, 3.0])
print(a[:, np.newaxis] + b)
'''
[[ 1.  2.  3.]
 [11. 12. 13.]
 [21. 22. 23.]
 [31. 32. 33.]]
'''

newaxis インデックス演算子は a に新しい軸を挿入し、これを 2 次元の 4×1 配列にする。4×1 配列と形状 (3,) を持つ b を組み合わせると、4×3 配列が得られる。