[NumPy超入門]多次元配列から最大値/最小値を求めてみよう:Pythonデータ処理入門
NumPyには最大値や最小値を求める関数/メソッドがとてもたくさん用意されています。それらの幾つかと最大値や最小値を求める際に注意が必要なNaN値の扱いについて見ていきます。
連載概要
本連載はPythonについての知識を既にある程度は身に付けている方を対象として、Pythonでデータ処理を行う上で必須ともいえるNumPyやpandas、Matplotlibなどの各種ライブラリの基本的な使い方を学んでいくものです。そして、それらの使い方をある程度覚えた上で、それらを活用してデータ処理を行うための第一歩を踏み出すことを目的としています。
最大値の取得
NumPyの多次元配列(numpy.ndarrayオブジェクト)に格納されている要素から最大値を抽出するのに使える関数やメソッドには幾つかの種類があります。
関数/メソッド | 説明 | NaNがあった場合 |
---|---|---|
numpy.amax関数 | 引数に指定した配列の要素から最大値を返す | NaNを返す |
numpy.nanmax関数 | 引数に指定した配列の要素から最大値を返す | NaNを無視する |
numpy.ndarray.maxメソッド | 呼び出しに使用した配列の要素から最大値を返す | NaNを返す |
numpy.maximum関数 | 引数に指定した2つの配列を対応する要素ごとに比較して大きい方の値を取り出し、それらを要素とする新しい配列を作成して戻り値とする | NaNを返す |
numpy.fmax関数 | 引数に指定した2つの配列を対応する要素ごとに比較して大きい方の値を取り出し、それらを要素とする新しい配列を作成して戻り値とする | NaNを無視する |
numpy.argmax関数 | 最大値を含んでいる要素のインデックスを返す | NaNが含まれているインデックス位置を返す |
numpy.ndarray.argmaxメソッド | 最大値を含んでいる要素のインデックスを返す | NaNが含まれているインデックス位置を返す |
最大値を取得する関数/メソッド |
以下ではこれらの関数について簡単に見ていきましょう。
numpy.amax関数
numpy.amax関数の構文を以下に示します。
numpy.amax(a, axis=None, out=None, keepdims=<no value>)
パラメーターの意味は以下の通りです。
- a:最大値を調べたいndarrayオブジェクトを指定
- axis:最大値を求めたい軸(0始まり)
- out:結果を格納する配列。numpy.amax関数が算出する結果と同じ形状でなければならない
- keepdims:Trueを指定すると戻り値の次元数が元のndarrayオブジェクトと同じになる
numpy.amax関数に配列だけを渡したときには、その配列の全要素の中で最大の値が返されます。以下はその例です。
a = np.arange(12).reshape((3, 4))
print(a)
# 出力結果:
#[[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
m = np.amax(a)
print(m) # 11
この例では配列のみを渡しているので、 その中の最大値が返されます(このときには、元の配列を1次元化したものが渡されます)。
axisに最大値を求める際にどの軸に沿って進むかを指定することも可能です。以下は行方向に最大値を検索する例です。
m = np.amax(a, axis=0) # 行方向
print(m) # [ 8 9 10 11]
この例では「axis=0」と指定しているので、行インデックスが小さい方から大きい方へと進みながら最大値が検索されて、見つかった最大値(11)が含まれる行が戻り値になっています。
一方、「axis=1」を指定した例が以下です。
m = np.amax(a, axis=1) # 列方向
print(m) # [ 3 7 11]
この例では各行を列インデックスが小さい方から大きい方へと進みながら最大値を検索して、最大値(11)が含まれる列が戻り値になっています。
実際には以下のように行と列を(さらに次元数が多ければ、それらの軸の方向も)タプル形式で渡すことも可能です。
m = np.amax(a, axis=(0, 1)) # 行方向/列方向
print(m) # 11
この場合には、最大値がそのまま取り出されます。
出力を新規の配列に保存しておきたいときにはoutに、numpy.amax関数の戻り値と同じ形状となる配列を渡します。
o = np.empty_like(a[0])
m = np.amax(a, axis=0, out=o)
print(m) # [ 8 9 10 11]
print(o) # [ 8 9 10 11]
o = np.empty_like(a[:, 0])
m = np.amax(a, axis=1, out=o)
print(m) # [ 3 7 11]
print(o) # [ 3 7 11]
最初の例ではnumpy.amax関数に「axis=0」を指定しています。そのため、戻り値は4要素の1次元配列です。よって、numpy.empty_like関数を使って、 そうした配列を作成している点に注意してください。
ここで使用しているnumpy.empty_like関数は、引数と指定した配列と同じ形状で、同じデータ型を要素の型とする配列を新規に作成するものです。
次の例では「axis=1」と指定しているので、戻り値は3要素の1次元配列になります。これに合わせて、列方向の形状を指定するためにempty_like関数に「a[:, 0]」を渡しています。
最後のkeepdimsは戻り値の次元数を、元の配列と同じようにするかどうかの指定です。以下に例を示します。
m = np.amax(a, keepdims=True)
print(m) # [[11]]
m = np.amax(a, axis=0, keepdims=True)
print(m) # [[ 8 9 10 11]]
ところでNumPyで扱うデータには、データがあるはずのところなのにデータがない(欠損している)といった場合もあります。NumPyではこれらはNaN(Not a Number)値として扱うことが一般的です。NaN値を表すのに、NumPyではnp.nanオブジェクトが使われます。
どうしてそんな話を突然したかというと、numpy.amax関数は配列中にNaN値があった場合に、それらを最大値として取り出すからです。
a = np.array([np.nan, 0, 1])
m = np.amax(a)
print(m) # nan
このやり方だと問題があるときには、次に紹介するnumpy.nanmax関数を使うとよいでしょう。
numpy.nanmax関数
Copyright© Digital Advantage Corp. All Rights Reserved.