HOWTO · NumPy

Python NumPy の要素ごとの除算

Python の NumPy 配列で要素ごとの除算を実行するために使用できる主なメソッドは、numpy.divide()関数と/演算子の 2つです。

このページの内容

NumPy 配列の対応する値を割るには、numpy.divide(x1, x2) または x1 / x2 を使います。どちらも要素ごとの真の除算を行い、配列を返します。out や where などの省略可能な引数で結果を制御したい場合は、関数形式を使います。

numpy.divide() を使う

numpy.divide() では、最初に被除数、次に除数を指定します。形状が一致する配列では、最初の配列の各値を、2番目の配列の同じ位置にある値で割ります。返された配列を後で使う場合は、変数に代入します。out 引数は省略できます。省略すると NumPy が結果の配列を新しく作成して返します。結果を既存の配列に格納したい場合は、形状とデータ型が適合する配列を渡します。

次の例を実行します。

このセクションのコードと表示されるラベルや出力は英語のままです。

import numpy as np

numerators = np.array([12, 18, 24])
denominators = np.array([3, 6, 8])
by_function = np.divide(numerators, denominators)
destination = np.array([0.0, 0.0, 0.0])
np.divide(numerators, denominators, out=destination)
by_operator = numerators / denominators
print(by_function)
print(by_operator)
print(destination)
[4. 3. 3.]
[4. 3. 3.]
[4. 3. 3.]

最初の関数呼び出しでは out を省略しているため、新しい配列が返されます。2回目の呼び出しは、結果と同じ形状およびデータ型で作成した destination に値を書き込みます。演算子形式にも同じ入力を使うので、3つの配列には同じ商が入ります。入力は整数ですが、真の除算の結果は浮動小数点数になります。

/ 演算子を使う

多くの式では、/ が NumPy 配列を要素ごとに割る最も簡潔で分かりやすい方法です。result = numerators / denominators のように書くと、オペランドが位置ごとに計算され、結果の配列を変数に代入したり、インデックスで参照したり、別の NumPy 演算に渡したりできます。オペランドの一方がスカラーの場合や、2つの配列の形状が適合する場合は、NumPy の配列演算規則に従って計算されます。

この演算子は、整数除算専用の演算ではありません。整数配列に / を使うと真の除算が行われ、商は浮動小数点数で表されます。これは、切り下げ除算を行う Python の // とは異なります。必要な演算に合わせて演算子を選び、小数の商が必要な場合は // を使わないでください。

ブロードキャスト、データ型、ゼロ除算

同じ形状の配列では、対応する要素同士が直接割られます。NumPy は、形状が適合する配列をブロードキャストすることもできます。次元は右端から比較され、各次元の組は値が等しいか、どちらかが 1 である必要があります。たとえば、形状が (2, 3) の2次元配列は、形状が (3,) の1次元配列で割ることができ、各行に同じ除数が適用されます。ブロードキャストの規則を満たさない形状同士では、要素ごとの除算はできません。形状が合わない場合は、両方のオペランドで array.shape を確認してください。

結果のデータ型は、入力のデータ型と除算の種類によって決まります。特に、/ または numpy.divide() に整数を渡すと、商を整数に切り捨てず、真の除算の結果が得られます。後続の処理で特定のデータ型が必要な場合は、除算後に意図を明確にして型変換し、小数部分が失われないか確認してください。

真の除算では、/ と numpy.divide() は整数入力から浮動小数点数の結果を生成します。そのため、ゼロでない分子をゼロで割ると無限大になり、0 / 0 は nan になることがあり、実行時警告も発生します。浮動小数点数の入力でも同様です。ここで扱うのは真の除算であり、// による切り下げ除算は別の演算です。ゼロ除数に当たる位置を計算から除外するには、まず出力配列を初期化してから、numpy.divide(a, b, out=result, where=b != 0) を使います。条件が偽の位置には、初期化時の値がそのまま残ります。後続の計算に適した埋め値を選び、除外した位置を別途どう扱うかも決めてください。

除算方法を選ぶ

簡潔な要素ごとの商を式で求めるなら / を使います。既存の配列に結果を格納する out や、計算する位置を選ぶ where など、関数の引数が役立つ場合は numpy.divide() を使います。どちらの形式でも、オペランドの形状が適合することを確認し、データの型に応じてゼロ除数をどう扱うか決めてください。こうした点を確認しておくと、ベクトル、行列、ブロードキャスト可能な入力にもコードを応用しやすくなります。