複数のNumPy配列ndarrayの要素ごとの最大値・最小値を取得
複数のNumPy配列ndarray
の要素ごとの最大値・最小値を算出して新たなnumpy.ndarray
を生成するにはnumpy.maximum()
, numpy.fmax()
, numpy.minimum()
, numpy.fmin()
を使う。
- numpy.maximum — NumPy v1.17 Manual
- numpy.fmax — NumPy v1.17 Manual
- numpy.minimum — NumPy v1.17 Manual
- numpy.fmin — NumPy v1.17 Manual
numpy.maximum()
, numpy.fmax()
, numpy.minimum()
, numpy.fmin()
自体は2つのnumpy.ndarray
のみを対象とするが、reduce()
を利用することで3つ以上のnumpy.ndarray
を処理することが可能。
ここでは以下の内容について説明する。
- NumPy配列
ndarray
の要素ごとの最大値を取得:maximum()
,fmax()
- 基本的な使い方
- 形状
shape
が異なる場合
- NumPy配列
ndarray
の要素ごとの最小値を取得:minimum()
,fmin()
maximum()
とfmax()
、minimum()
とfmin()
の違いreduce()
で集約- 複数のNumPy配列
ndarray
に適用 - 1つのNumPy配列
ndarray
に適用
- 複数のNumPy配列
なお、単独のnumpy.ndarray
の全体・行ごと・列ごとの最大値・最小値はmax()
, min()
メソッドなどで取得できる。
import numpy as np
a = np.arange(6).reshape(2, 3)
print(a)
# [[0 1 2]
# [3 4 5]]
print(a.max())
# 5
print(a.max(axis=0))
# [3 4 5]
print(a.max(axis=1))
# [2 5]
NumPy配列ndarrayの要素ごとの最大値を取得: maximum(), fmax()
numpy.maximum()
, numpy.fmax()
の違いは後述の欠損値nan
の扱いのみ。それ以外はどちらも全く同じ。
基本的な使い方
numpy.maximum()
, numpy.fmax()
の第一引数、第二引数に対象とするnumpy.ndarray
を指定する。
a = np.array([0, 1, 2])
b = np.array([2, 0, 6])
print(np.maximum(a, b))
# [2 1 6]
print(np.fmax(a, b))
# [2 1 6]
リストでもよい。
l_a = [0, 1, 2]
l_b = [2, 0, 6]
print(np.maximum(l_a, l_b))
# [2 1 6]
print(np.fmax(l_a, l_b))
# [2 1 6]
スカラー値でもよいが、組み込み関数max()
でも同じ結果が得られる。
print(np.maximum(0, 2))
# 2
print(np.fmax(0, 2))
# 2
print(max(0, 2))
# 2
形状shapeが異なる場合
NumPyにおいて、形状shape
が異なるnumpy.ndarray
同士の演算では、可能な場合はブロードキャストによって形状が揃えられる。
- 関連記事: NumPyのブロードキャスト(形状の自動変換)
a_2d = np.arange(6).reshape(2, 3)
print(a_2d)
# [[0 1 2]
# [3 4 5]]
print(b)
# [2 0 6]
print(a_2d + b)
# [[ 2 1 8]
# [ 5 4 11]]
numpy.maximum()
, numpy.fmax()
においてもブロードキャストが行われる。
print(np.maximum(a_2d, b))
# [[2 1 6]
# [3 4 6]]
print(np.fmax(a_2d, b))
# [[2 1 6]
# [3 4 6]]
ブロードキャストできない場合はエラーとなる。
a_mismatch = np.array([0, 1, 2, 3])
# print(np.maximum(a_mismatch, b))
# ValueError: operands could not be broadcast together with shapes (4,) (3,)
# print(np.fmax(a_mismatch, b))
# ValueError: operands could not be broadcast together with shapes (4,) (3,)
第一引数、第二引数のいずれかがスカラー値でもOK。各要素がスカラー値と比較される。
print(np.maximum(a_2d, 2))
# [[2 2 2]
# [3 4 5]]
print(np.fmax(a_2d, 2))
# [[2 2 2]
# [3 4 5]]
print(np.maximum(2, a_2d))
# [[2 2 2]
# [3 4 5]]
print(np.fmax(2, a_2d))
# [[2 2 2]
# [3 4 5]]
NumPy配列ndarrayの要素ごとの最小を取得: minimum(), fmin()
numpy.minimum()
, numpy.fmin()
もnumpy.maximum()
, numpy.fmax()
と同じ使い方。サンプルコードのみをいくつか示す。
なお、numpy.minimum()
, numpy.fmin()
の違いも後述の欠損値nan
の扱いのみ。それ以外はどちらも全く同じ。
基本的な使い方。
a = np.array([0, 1, 2])
b = np.array([2, 0, 6])
print(np.minimum(a, b))
# [0 0 2]
print(np.fmin(a, b))
# [0 0 2]
ブロードキャストおよびスカラー値との処理。
a_2d = np.arange(6).reshape(2, 3)
print(a_2d)
# [[0 1 2]
# [3 4 5]]
print(np.minimum(a_2d, b))
# [[0 0 2]
# [2 0 5]]
print(np.fmin(a_2d, b))
# [[0 0 2]
# [2 0 5]]
print(np.minimum(a_2d, 2))
# [[0 1 2]
# [2 2 2]]
print(np.fmin(a_2d, 2))
# [[0 1 2]
# [2 2 2]]
numpy.maximum()
, numpy.fmax()
と同じく、引数にリストを指定することもできる。例は省略。
maximum()とfmax()、minimum()とfmin()の違い
numpy.maximum()
とnumpy.fmax()
、numpy.minimum()
とnumpy.fmin()
との違いは欠損値nan
の扱い。
第一引数、第二引数のnumpy.ndarray
などにnan
が含まれる場合、numpy.maximum()
, numpy.minimum()
では結果がnan
となり、numpy.fmax()
, numpy.fmin()
はnan
ではないほうが結果となる。
print(np.maximum([np.nan, np.nan], [np.inf, 0]))
# [nan nan]
print(np.fmax([np.nan, np.nan], [np.inf, 0]))
# [inf 0.]
print(np.minimum([np.nan, np.nan], [np.inf, 0]))
# [nan nan]
print(np.fmin([np.nan, np.nan], [np.inf, 0]))
# [inf 0.]
reduce()で集約
numpy.maximum()
, numpy.fmax()
, numpy.minimum()
, numpy.fmin()
のような2つのオブジェクト(numpy.ndarray
など)を引数とするユニバーサル関数ufunc
はreduce()
というメソッドを持つ。
reduce()
にリストなどのイテラブルを指定するとufunc
がその要素に対して累積的に適用され結果が集約される。
ufunc.reduce(x)
は基本的には... ufunc(ufunc(ufunc(x[0], x[1]), x[2]), x[3]) ...
に等しい。
複数のNumPy配列ndarrayに適用
numpy.maximum()
を例とすると以下のようになる。
a = np.array([0, 1, 2])
b = np.array([3, 0, 6])
c = np.array([1, 2, 3])
print(np.maximum.reduce([a, b, c]))
# [3 2 6]
以下のような処理と同じ。
print(np.maximum(np.maximum(a, b), c))
# [3 2 6]
numpy.fmax()
, numpy.minimum()
, numpy.fmin()
でも同様。
print(np.fmax.reduce([a, b, c]))
# [3 2 6]
print(np.minimum.reduce([a, b, c]))
# [0 0 2]
print(np.fmin.reduce([a, b, c]))
# [0 0 2]
reduce()
の引数にはリストなどのイテラブルを指定する必要がある。リストではなくタプルなどでもいいが、各オブジェクトをそのままカンマ区切りで指定するとエラー。
print(np.maximum.reduce((a, b, c)))
# [3 2 6]
# print(np.maximum.reduce(a, b, c))
# TypeError: data type not understood
なお、reduce()
を使うと関数が繰り返し適用されると書いたが、各オブジェクトの形状が異なる場合、NumPy1.16.4
時点ではエラーになった。元の関数(ここではnumpy.maximum()
)を繰り返すと問題ない。
a_2d = np.arange(6).reshape(2, 3)
print(a_2d)
# [[0 1 2]
# [3 4 5]]
# print(np.maximum.reduce([a_2d, b, c]))
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
print(np.maximum(np.maximum(a_2d, b), c))
# [[3 2 6]
# [3 4 6]]
numpy.ndarray
とスカラー値が混在する場合も同じ。
# print(np.maximum.reduce([4, b, c]))
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
print(np.maximum(np.maximum(4, b), c))
# [4 4 6]
ソースコードを追っていないのでバグなのかこういう仕様なのかは未確認だが要注意。
1つのNumPy配列ndarrayに適用
reduce()
の引数に一次元のnumpy.ndarray
を指定すると、要素に対して順に関数(ここではnumpy.maximum()
)が適用される。
この場合、numpy.ndarray
のmax()
メソッドや組み込み関数max()
で同様の結果が得られるので、numpy.maximum()
やreduce()
を使う必要はない。
print(a)
# [0 1 2]
print(np.maximum.reduce(a))
# 2
print(a.max())
# 2
print(max(a))
# 2
多次元のnumpy.ndarray
も同様。
ufunc.reduce(x)
は... ufunc(ufunc(ufunc(x[0], x[1]), x[2]), x[3]) ...
に等しいという考え方の通りに処理される。
これもmax()
メソッドで引数axis
を指定すれば同様の結果が得られる。あえてnumpy.maximum()
やreduce()
を使う必要はない。
a_2d = np.array([[0, 1, 2], [3, 0, 6], [1, 2, 3]])
print(a_2d)
# [[0 1 2]
# [3 0 6]
# [1 2 3]]
print(np.maximum.reduce(a_2d))
# [3 2 6]
print(np.maximum(np.maximum(a_2d[0], a_2d[1]), a_2d[2]))
# [3 2 6]
print(a_2d.max(axis=0))
# [3 2 6]