[NumPy] ブロードキャスト

[NumPy] ブロードキャスト

ブロードキャスト

 配列の演算規則の記事で解説したように、配列に 1 を加えると、配列のすべての要素に 1 を加えるという処理が行われます。

# NumPyをインポート
import numpy as np

# 1次元配列の定義
x = np.array([10, 20, 30])

# 配列の各要素に1を加える
print(x + 1)
[11 21 31]

 これはとても便利な記法です。なぜなら、こうした記法が許されていないとすれば、配列のすべての要素に 1 を加えるためには、もう1つ別の配列を用意しなければならないからです。

# NumPyをインポート
import numpy as np

# 1次元配列の定義
x = np.array([10, 20, 30])
y = np.array([1, 1, 1])

# 配列xの各要素に1を加える
print(x + y)
[11 21 31]

 あるいは、こうした操作を行なうための関数やメソッドを用意するという方法もあるかもしれませんが、いずれにしても「+1」ほど簡易な記述にはならないでしょう。

 実は、この操作は NumPy のブロードキャスト (broadcasting) とよばれる機能の一例です。ブロードキャストは形状の異なる配列同士で演算の実行を可能にします。NumPy において、Python の数値(整数や浮動小数点数)はスカラーとよばれる 0 次元配列として扱われます。1 次元配列にスカラーを加える場合、下図のようにスカラーを引き伸ばして仮想的な 1 次元配列を作って演算処理を実行することになります。
 
 
 NumPy ブロードキャスト01
 
 様々な形状の配列同士でブロードキャストが適用されます。たとえば、2 次元配列と 1 次元配列を加える場合、1 次元配列を 2 次元配列の形状に合わせてブロードキャストします(引き伸ばします)。
 
 
 NumPy ブロードキャスト02
 
 実際にコードを書いて確認してみましょう。

# NumPyをインポート
import numpy as np

# 1次元配列の定義
x = np.array([[10, 20, 30],
              [40, 50, 60],
              [70, 80, 90]])

y = np.array([1, 1, 1])

# x + y
print(x + y)
[[11 21 31]
 [41 51 61]
 [71 81 91]]

 次は列ベクトルと 1 次元配列を掛けてみます。
 この場合、お互いが他方の配列の形状に合わせてブロードキャストされます。
 
 NumPy ブロードキャスト配列積
 
 この操作もコードで確認しておきます。

# NumPyをインポート
import numpy as np

# 列ベクトルを定義
x = np.array([[10],
              [20],
              [30]])

# 1次元配列を定義
y = np.array([1, 2, 3])

# x * y
print(x * y)
[[10 20 30]
 [20 40 60]
 [30 60 90]]

 実際には、ブロードキャストは図に描いたようなコピーを行なうことなく(メモリを割り当てることなく)配列演算を処理します(だからこそ高速なのです)。上の説明はあくまで概念的なもの(あるいはブロードキャストの演算ルール)と考えてください。