NumPyのargmax関数は、配列内の最大値のインデックスを返す関数です。これは、ndarray.argmaxメソッドとしても用意されています。最大値のインデックスを取得することによって、単純に最大値を取得する場合よりも幅広い操作が可能になります。そのためにもぜひ、argmaxの使い方をここでご確認頂ければと思います。
インデックスの配列を使いこなすための全スキル
NumPyの配列は、様々なスライスのテクニックが用意されています。その中でも特に重要なのは、インデックスの配列によるスライスのテクニックでしょう。これらに関して詳しくは、『NumPyの配列のスライスの必須テクニックまとめ』ですべてまとめています。インデックス配列を使いこなすためにも、ぜひご確認頂ければと思います。
NumPy配列の最大値の操作まとめ
NumPy配列の最大値を操作する全方法については、『NumPy配列の最大値やそのインデックスを取得する関数とメソッドまとめ』ですべてまとめています。ぜひ一度ご確認ください。
1. 書式
まずは、書き方と引数を確認しておきましょう。
書き方:
np.argmax(a, axis=None, out=None)
パラメーター:
引数 | 型 | 解説 |
a | array_like | 配列を渡します。 |
axis* | int | どの軸を基準に最大値を求めるかを指定します。デフォルト(None)では配列全体の要素の中の最大値を1つだけ取得します |
out* | array | ここで指定した配列を、関数の戻り値で上書きします。指定する配列のshapeとdtypeが適切である必要があります。 |
* はオプション引数であることを示します。 |
戻り値:
ndarray: 最大値のインダイス(インデックスの複数形)を要素とした配列を戻します。生成される配列のshapeは、元の配列のshapeから、指定したaxisを削除したものになります。 |
一緒に確認したい関数:
書き方:
ndarray.argmax(axis=None, out=None)
2. サンプルコード
それでは、実際のコードで使い方を確認していきましょう。
なお、関数のnp.argmaxとメソッドのndarray.argmaxは、ほとんど同じなので、ここでは関数をメインに見ていきます。
1次元配列の場合
まずは、以下の1次元配列を例に見てみましょう。
# 1次元配列を作成
import numpy as np
rng = np.random.default_rng()
arr = rng.integers(1, 10, (5, ))
arr
この配列をnp.argmaxに渡すと、以下のように最大値のインデックスを返します。
# 最大値のインデックスを取得
np.argmax(arr)
なお、配列内に同じ最大値が複数ある場合は、最初のインデックスを返します。
値を参照したい場合は、[]
でスライスします。スライスについては『NumPyの配列のスライスの必須テクニックまとめ』で解説しています。
# スライスして値を参照
arr[3]
多次元配列の場合
2次元配列以上の配列を渡した場合は、それを1次元配列化した時のインデックスを返します。
以下のコードをご覧ください。
# 2次元配列の作成
rng = np.random.default_rng()
arr = rng.integers(1, 10, (2, 3))
arr
# 全要素をフラット化した場合の最大値のインデックスを取得
np.argmax(arr)
値を参照したい場合は、ndarray.flattenメソッドで配列を1次元化してからでスライスします。
# 値を参照する際は、flattenメソッドを併用
arr.flatten()[4]
または、unravel_indexを使って、次のように書くと2次元配列のままスライスするためのインダイスを取得することができます。
ind = np.unravel_index(np.argmax(arr, axis=None), arr.shape)
ind
arr[ind]
なお、unravel_indexは、あるインダイスの配列の要素を指定のshapeの配列に変換した場合のインダイスに変換してくれる関数です。これも便利なので覚えておくと良いです。以下のコードで使い方を確認しておきましょう。
import numpy as np
rng = np.random.default_rng()
arr = rng.integers(-10, 10, (12, ))
arr
>>> # 最大値のインデックス
>>> ind = np.argmax(arr)
>>> ind
8
>>> # indをshape(2, 6)の2次元配列のインデックスに変換
>>> np.unravel_index(ind, (2, 6))
(1, 2)
>>> # indをshape(2, 2, 3)の3次元配列のインデックスに変換
>>> np.unravel_index(ind, (2, 2, 3))
(1, 0, 2)
軸方向の指定
オプション引数axis=
で、多次元配列のどの軸方向の最大値のインデックスを取得するかを指定することができます。以下の2次元配列を使って確認しましょう。
import numpy as np
rng = np.random.default_rng()
a = rng.integers(1, 10, (2, 3))
a
axis=-1で1次元軸(横軸)を軸として最大値のインデックスを返します。以下で確認しましょう。
# 1次元軸(横軸)での最大値のインダイスを取得
ind = np.argmax(a, axis=-1)
ind
このインダイスから各行の最大値を一括取得するには、次の書き方が便利です。
# 行ごとの最大値を一括で取得
ind_array = np.expand_dims(ind, axis=-1) #インデックス配列の次元数をaに合わせる
np.take_along_axis(a, ind_array, axis=-1) # 多次元配列からの値の取得に便利
簡潔に解説します。
expand_dimsは配列の次元数を増やす関数です。これによって、元の配列a の次元数とインダイス配列ind の次元数を揃えています。np.take_arlong_axisは多次元配列から指定のインデックス番号の要素を一括して取得する関数です。こちらの関数では、元の配列a とインダイス配列の次元数が揃っている必要があります。
argmaxは、axis=0で2次元軸(縦軸)を軸として最大値のインデックスを返します。以下で確認しましょう
# 2次元軸(縦軸)での最大値のインダイスを取得
ind = np.argmax(a, axis=0)
ind
これは最大値が存在する列のインデックスです。各列の最大値を一括で取得するには、次のように書きます。
# 列ごとの最大値を一括で取得
ind_array = np.expand_dims(ind, axis=0) #インデックス配列の次元数をaに合わせる
np.take_along_axis(a, ind_array, axis=0) # 多次元配列からの値の取得に便利
3次元配列の場合でも次元数が増えるだけで法則性は同じです。
戻り値で既存の配列を上書き
np.argmax
関数では、使うことはまずないと思いますが、オプション引数 out= で、既存の配列を戻り値の配列で上書きすることができます。この時、お互いの配列とデータ型の形状が一致している必要があります。
以下のコードでご確認ください。
# 配列を作成
import numpy as np
rng = np.random.default_rng()
arr = rng.integers(5, size=(2, 5))
arr
# 上書きする配列を作成
x = np.zeros(5, dtype=int)
x
# np.argmaxの戻り値でxを上書き
np.argmax(arr, axis=0, out=x)
x
3. まとめ
以上が、np.argmax
関数の使い方です。
ページ中で解説している np.expand_dims や np.take_along_axis、np.unravel_index の書き方もしっかり頭に入れておきましょう。
ndarray.argmax
メソッドも使い方は同じですが、対象となる配列を渡す位置が異なります。以下にサンプルコードを貼っておきます。
import numpy as np
# 配列を生成
rng = np.random.default_rng()
arr = rng.integers(0, 10, (2, 3))
print('arr:\n', arr, '\n')
# メソッドなので配列を前に書く
print('arr.argmax()\n', arr.argmax(), '\n')
# axisの指定
print('arr.argmax(axis=0)\n', arr.argmax(axis=0), '\n')
# outの指定
a_out = np.zeros(2, dtype=int)
arr.argmax(axis=1, out=a_out)
print('a_out:\n', a_out)
コメント