このページのリンクには広告が含まれています。 プログラミング

【Python】NumPy配列のブロードキャストとは?ルールを解説!

NumPyのブロードキャストは、異なる形状(shape)の配列同士の演算を可能にする便利な機能です。

この記事ではブロードキャストがどのように適用されるか、そのルールを具体例とともにご紹介します。

ぜひ参考にしてみてください!

ブロードキャストのルール

次元数(ndim)を揃える

2つの配列の次元数が異なる場合、次元数の少ない方の前に「1」の次元を追加して形を揃えます。

各次元のサイズを比較する

2つの配列の対応する次元について、以下のいずれかを満たせば、その次元は互換性があります:

  • 両方の配列で次元のサイズが同じ
  • どちらかの次元のサイズが 1(この場合、サイズが 1 の配列はその次元で拡張される)

ブロードキャストが可能ならば、拡張された形状で演算が行われる

互換性のある次元は、自動的に繰り返されて(仮想的に拡張されて)演算が実行されます。

具体例

同じ形状の場合

import numpy as np

A = np.array([[1, 2, 3], [4, 5, 6]])  # (2, 3)
B = np.array([[10, 20, 30], [40, 50, 60]])  # (2, 3)

print(A + B)

# 実行結果
#[[11 22 33]
# [44 55 66]]

AB は同じ形 (2,3) なので、通常の要素ごとの演算が行われます。

片方の配列に次元 1 がある場合

A = np.array([[1, 2, 3]])  # (1, 3)
B = np.array([[10], [20], [30]])  # (3, 1)

print(A + B)

# 実行結果
# A: [[1, 2, 3]]
# B: [[10],
#     [20],
#     [30]]


# 結果: [[11, 12, 13],
#        [21, 22, 23],
#        [31, 32, 33]]

A.shape = (1, 3), B.shape = (3, 1) のため、以下のようにブロードキャストされます:

A: [[1, 2, 3]]
B: [[10],
    [20],
    [30]]

結果: [[11, 12, 13],
       [21, 22, 23],
       [31, 32, 33]]

配列Bが配列Aと同じshapeに伸長されて処理が行われます。

1次元配列と2次元配列の演算

A = np.array([[1, 2, 3], [4, 5, 6]])  # (2, 3)
B = np.array([10, 20, 30])  # (3,)

print(A + B)

# 実行結果
#[[11, 22, 33],
# [14, 25, 36]]

B.shape(3,) なので、(1,3) に拡張されて (2,3) と互換性が取れます。

ブロードキャストが適用されないケース

ブロードキャストが適用されるためには、すべての次元が

  • 同じサイズ または
  • どちらかが 1
    のいずれかでなければなりません。

例えば、次のケースではエラーになります:

A = np.array([[1, 2, 3], [4, 5, 6]])  # (2, 3)
B = np.array([10, 20])  # (2,)

print(A + B)  # ブロードキャストできないためエラー

(2,3)(2,) は互換性がなく、ブロードキャストできません。

ブロードキャストのメリット

コードの簡潔化

ブロードキャストを活用すると、明示的なループを書かずに簡潔なコードで記述できます。
例えば、次のような処理をforループなしで実現できます。

import numpy as np

A = np.array([[1, 2, 3], [4, 5, 6]])  # (2, 3)
B = np.array([10, 20, 30])  # (3,)

# ブロードキャストを利用した計算
C = A + B
print(C)

通常のループを使うとこうなります:

C = []
for row in A:
    C.append([row[i] + B[i] for i in range(len(B))])
print(C)

ブロードキャストを使うことで、ループなしでシンプルな書き方が可能になります。

メモリ効率の向上

ブロードキャストは、メモリを無駄に消費せずに計算を行うことができます。
例えば、(1, 3) の形状の配列 B(2, 3) にコピーすることなく、仮想的に拡張して計算を行います。
これにより、不要なメモリの消費を抑えることができます。

import numpy as np

A = np.array([[1, 2, 3], [4, 5, 6]])  # (2, 3)
B = np.array([10, 20, 30])  # (3,)

# メモリ効率を考えた演算
C = A + B
print(C)

追加のメモリを確保せずに計算ができるため、大規模データ処理にも有効です。

まとめ

ブロードキャストの基本ルール

  1. 形状をそろえるために、必要ならば次元数を増やす(1 を前に追加)
  2. 各次元ごとに、サイズが一致するか、一方が 1 なら拡張可能
  3. ブロードキャストが成立すれば、要素ごとの演算が可能になる

以上がNumPyの配列のブロードキャストのルールです。ブロードキャストをうまく活用すると、for ループを使わずに効率的に計算を行えます!

大規模な数値計算をする方などは、ぜひ身に着けておきたいですね!

Python初心者におすすめの学習サービス

オンラインPython学習サービス「PyQ™(パイキュー)」:プログラミング初心者に優しいオンラインPython学習サービス。プログラミングを始めたけど、何かを作れるレベルには至っていない人におすすめ。実用的なPythonコードを実装することができる。

  • この記事を書いた人
  • 最新記事

-プログラミング