1. Home
  2. プログラマーのための線形代数
  3. NumPyの使い方
  4. 配列のブロードキャスト

配列のブロードキャスト

プログラミングの際は、基本的にサイズが異なる配列同士では足し算や引き算などの演算を行うことができません。そのため、いちいち配列のサイズを変更する必要があります。しかしNumPyではブロードキャスティングというテクニックがあり、それを駆使することでコードを非常にシンプルにすることができます。

このページでは、このブロードキャストが何かということと、その使い方について解説します。

当ページでわかること

  • ブロードキャストとは何か
  • 実務上覚えておくべき 3 つのブロードキャスト

配列演算の制限

配列の演算は基本的には同じサイズ同士である必要があります。たとえば、以下は 1 行 3 列の配列同士の足し算です。

In [1]:
# 同じサイズの配列同士は演算が可能
import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6]) 
c=a+b
print(c)
[5 7 9]

これが異なるサイズ同士になるとエラーになります。以下は 1 行 3 列と 1 行 4 列の配列同士を足し算しようとしたものです。

In [2]:
# 異なるサイズの配列同士は基本的に演算が不可能
import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6,7]) 
c=a+b
print(c)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/var/folders/nc/20npdqc94vbgzs77h4khjv7w0000gn/T/ipykernel_89586/3681869571.py in <module>
      3 a = np.array([1,2,3])
      4 b = np.array([4,5,6,7])
----> 5 c=a+b
      6 print(c)

ValueError: operands could not be broadcast together with shapes (3,) (4,) 

このように基本的には、配列同士の演算はサイズが同じもの同士でしか行えません。そして、この制限はさまざまな演算の効率を本当に大きく阻害してしまいます。しかし有難いことに、NumPyには、異なるサイズの配列同士でも演算ができるような仕組みが備わっています。それがブロードキャストです。

配列のブロードキャスト

ブロードキャスト(ブロードキャスティング)とは、異なるサイズの配列同士の演算を可能にしている NumPy のメソッドのことです。この技術は NumPy で開発されたものですが、現在では、Theano や TensorFlow、Octave などの他の有名な数値計算ライブラリにも移植されています。

ここでは頻繁に見たり使ったりすることになる、NumPyの代表的な 3 つのブロードキャストを見ていきます。より高度なブロードキャストもありますが、実務上では、これらの 3 つを頭に入れておけば、まず問題ありません。

  • スカラーと 1 次元配列のブロードキャスト
  • スカラーと 2 次元配列のブロードキャスト
  • 1 次元配列と 2 次元配列のブロードキャスト

スカラーと 1 次元配列のブロードキャスト

1 つのスカラーと 1 次元配列の演算を行うと、そのスカラーと配列の各要素で計算が行われます。例として以下のコードでは 1 行 3 列の配列と 1 つのスカラーの足し算を行なっています。

In [1]:
import numpy as np
# 配列を定義
a = np.array([10,20,30])
# スカラーを定義
b = 2
# ブロードキャスト
c=a+b
print(c)
[12 22 32]

スカラーと 2 次元配列のブロードキャスト

1 つのスカラーと 2 次元配列の演算も上と同じです。例として以下のコードでは 3 行 3 列の配列と 1 つのスカラーの足し算を行なっています。

In [2]:
import numpy as np
# 配列を定義
a = np.array([
    [1,2,3],
    [4,5,6],
    [7,8,9]])
# スカラーを定義
b = 10
# ブロードキャスト
c=a+b
print(c)
[[11 12 13]
 [14 15 16]
 [17 18 19]]

1 次元配列と 2 次元配列のブロードキャスト

1 次元配列と 2 次元配列同士の演算の場合、互いの列数が同じなら、同じ列の要素同士で演算が行われます。列数が異なる場合はエラーになります。

In [3]:
import numpy as np
# 2次元配列を定義
a = np.array([
    [1,2,3],
    [4,5,6],
    [7,8,9]])
# 1次元配列を定義
b = [10, 20,30]
# ブロードキャスト
c=a+b
print(c)
[[11 22 33]
 [14 25 36]
 [17 28 39]]

以上の 3 つは実務上でもよく使うブロードキャストなので覚えておきましょう。

ブロードキャストができるケースできないケース

念のため、NumPyの配列でブロードキャストが可能なケースと不可能なケースについて簡単に解説しておきます。厳密に言うと、ブロードキャストが可能なのは、以下の 2 つの場合です。

  • 一方がスカラーである場合
  • 2 つの配列のどちらも列数が同じで、一方の配列の行数が 1 の場合

これ以外の場合はブロードキャストは行えません。例えば 2 行 3 列の配列と 1 行 2 列の配列同士ではブロードキャストはできず、エラーになります。

In [4]:
import numpy as np
# 2次元配列を定義
a = np.array([
    [1,2,3,],
    [4,5,6,]])
# 1次元配列を定義
b =np.array([10,20])
# ブロードキャスト
c=a+b
print(c)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/var/folders/nc/20npdqc94vbgzs77h4khjv7w0000gn/T/ipykernel_92078/1680444874.py in <module>
      7 b =np.array([10,20])
      8 # ブロードキャスト
----> 9 c=a+b
     10 print(c)

ValueError: operands could not be broadcast together with shapes (2,3) (2,) 

一緒に読んでおきたいページ