このガイドでは、初心者の視点から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のブロードキャストには、配列に対する操作の一貫性とフェイルセーフを実現するための厳密なルールがあります。
これらは、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)
|
次元は(4, 4)と(4, 2)です。
ブロードキャストされる次元は最初は1でなければならないので、ブロードキャストは失敗します。
ここで、配列の次元は(5, 3)と(3, )です。
配列bは次元が1つ少ない。
次元の比較は右から左へ行われるので、bは1次元目に沿って引き伸ばされています。
注意すべきは、複数の配列が複数の次元に沿ってブロードキャストされることがあることです。
配列aは(4, 4, 1, 2)の次元を持ち、配列bは(1, 4, 2)の次元を持ちます。
配列aは3次元に、配列bは1次元と2次元に伸張され、結果として(4, 4, 4, 2)の次元の配列が得られます。
この記事もチェック:Numpyとvstackメソッドを使って1次元配列を多次元配列に結合する方法
ブロードキャストのスピードメリット
Numpyのブロードキャストは、配列をループするよりも高速です。
最初の例を見てみましょう。
ユーザーはブロードキャストのメカニズムを使用しないことを決定し、配列上のすべての要素に同じ数を追加するために配列全体をループすることができます。
ループ処理は Python のループと連動するため、C 言語の実装のスピードが失われます。
第二に、NumPyではループの代わりにstridesを使用します。
サイズ0のstridesを設定することで、メモリのオーバーヘッドなしに要素を無限に繰り返すことができます。
この記事もチェック:Pythonの配列をNumpyやforループを使って初期化する3つの方法
まとめ
Numpyのブロードキャストは、異なる形状の2つの配列を高速かつメモリ効率よく処理する方法を提供します。
2つの配列をブロードキャストする前に、ユーザーはあるルールに注意する必要があります。