Numpyのブロードキャストの条件や使い方について解説する

スポンサーリンク

このガイドでは、初心者の視点からNumpyブロードキャストについて説明します。

このガイドでは予備知識がないことを前提にしていますので、基礎的なところから説明していきます。

スポンサーリンク

Numpyブロードキャストとは?

“ブロードキャスト “という用語は、算術演算中に異なる形状を持つ配列をnumpyがどのように扱うかを説明します。

ある制約のもとで、小さい方の配列は大きい方の配列に「ブロードキャスト」され、両者の形状が一致するようになります。

ブロードキャストは、PythonではなくC言語でループが発生するように、配列操作をベクトル化する手段を提供します。

それを理解するために、小さな例を挙げてみましょう。

NumPyのブロードキャスト機構を理解するために、2つの配列を異なる次元に追加します。

import numpy as np
 
arr = np.arange(3)
result = arr + 4

一方、5.は単純な整数であり、理論的には0次元です。

両者は異なる次元であるため、Numpyは小さい方の配列を特定の軸に沿ってブロードキャスト(単純に引き伸ばす)し、数学的演算が行われるのに適した状態にしようと試みます。

a = np.arange(12).reshape(4, 3)
print("Shape of a is:", a.shape)
 
b = np.arange(4).reshape(4, 1)
print("Shape of b is:", b.shape)
 
print("Sum:
"
, a + b)

Numpyブロードキャストの条件

Numpyのブロードキャストには、配列に対する操作の一貫性とフェイルセーフを実現するための厳密なルールがあります。

これらは、numpyにおけるブロードキャストの一般的な2つのルールです。

  • NumPy の配列に対して操作を行うとき、NumPy は配列の形状を右から左へ要素ごとに比較します。2つの次元が等しいか、どちらかが1のときのみ互換性があります。2つの次元が等しい場合、配列はそのまま残されます。次元が1の場合は、その次元に沿って配列がブロードキャストされます。2つの条件のいずれも満たされない場合、NumPyはValueErrorを投げ、配列がブロードキャストできないことを示す。配列がブロードキャストされるのは、すべての次元が互換性を持っている場合のみです。
  • 比較される配列は、同じ次元数である必要はありません。比較される配列は、同じ次元数である必要はありません。小さい次元数の配列は、不足する次元に沿って簡単に拡大縮小することができます。

Numpyブロードキャスティングの実装

このルールをよりよく理解するために、いくつかの例を示します。

a = np.arange(16).reshape(4, 4)
print("Shape of a is:", a.shape)
 
b = np.arange(4).reshape(4, 2)
print("Shape of b is:", b.shape)
 
print("Sum:
"
, a + b)
a = np.arange(15).reshape(5, 3)
print("Shape of a is:", a.shape)
 
b = np.arange(3)
print("Shape of b is:", b.shape)
 
print("Sum:
"
, a + b)

互換性のある次元を持つ配列の和。

配列の次元が (4, 3) と (4, 1) であり、互換性がある。

a = np.arange(32).reshape(4, 4, 1, 2)
print("Shape of a is:", a.shape)
 
b = np.arange(8).reshape(1,4,2)
print("Shape of b is:", b.shape)
 
print("Shape of the sum:
"
, (a + b).shape)
Numpy Brod Example

次元は(4, 4)と(4, 2)です。

ブロードキャストされる次元は最初は1でなければならないので、ブロードキャストは失敗します。

Broadcast 4
Broadcast 3 1

ここで、配列の次元は(5, 3)と(3, )です。

配列bは次元が1つ少ない。

次元の比較は右から左へ行われるので、bは1次元目に沿って引き伸ばされています。

Broadcast 2
Broadcast 1

注意すべきは、複数の配列が複数の次元に沿ってブロードキャストされることがあることです。

配列aは(4, 4, 1, 2)の次元を持ち、配列bは(1, 4, 2)の次元を持ちます。

配列aは3次元に、配列bは1次元と2次元に伸張され、結果として(4, 4, 4, 2)の次元の配列が得られます。

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

Numpyのブロードキャストは、配列をループするよりも高速です。

最初の例を見てみましょう。

ユーザーはブロードキャストのメカニズムを使用しないことを決定し、配列上のすべての要素に同じ数を追加するために配列全体をループすることができます

ループ処理は Python のループと連動するため、C 言語の実装のスピードが失われます。

第二に、NumPyではループの代わりにstridesを使用します。

サイズ0のstridesを設定することで、メモリのオーバーヘッドなしに要素を無限に繰り返すことができます。

まとめ

Numpyのブロードキャストは、異なる形状の2つの配列を高速かつメモリ効率よく処理する方法を提供します。

2つの配列をブロードキャストする前に、ユーザーはあるルールに注意する必要があります。

タイトルとURLをコピーしました