lisz-works

技術系だけど関係ないこと多い系ブログ

numpyで配列から最大値を求める!

【スポンサーリンク】

Python ロゴ

Pythonで配列に入っている値から、最大値を求める方法です。

numpyというライブラリを使うことで、簡単に分かります!

使用するもの

使用するのは、numpyargmax()という関数です。

import numpy as np

arr.argmax()
np.argmax(arr)

ざっくりした使用方法は

  1. numpyをインポートする
  2. numpyの配列(array)を作成する
  3. argmax()で最大値を取得する

argmax()は、引数によって、最大値の求め方が変えられるという便利な代物。

それでは詳細をご紹介していきます!

numpy配列から最大値を求める

基本的な使用方法のサンプルはこんな感じ。

>>> import numpy as np
>>> arr = np.random.randint(10, size = (3,4))
>>> arr
array([[2, 0, 3, 4],
       [5, 3, 8, 3],
       [8, 0, 0, 1]])
>>> arr.argmax()
6
>>> # 横方向の最大値を求めてくれる
...
>>> np.argmax(arr, axis=0)
array([2, 1, 1, 0], dtype=int64)
>>>
>>> # 縦方向の最大値を求める
...
>>> np.argmax(arr, axis=1)
array([2, 2, 0], dtype=int64)
>>>

1次元配列でも使えます。

が、多次元配列でも効果を発揮するのが、このargmax()の強みですね。

取得できるのは、あくまで「位置」です。

なので、その値が欲しければ、取得した値をインデックスにして、値を取得しましょう!

>>> na = np.array([1,2,5,4,3])
>>> idx = na.argmax()    # idx = 2
>>> na[idx]
5
>>>

全体から最大値の位置を求める

例のような2次元配列の場合、先頭から数えてidx=6なので、6が返ってきます。

argmax関数

2次元配列を繋げて、1本の配列のように見ると分かりやすいです。

argmax関数 考え方

numpy 2次元配列の横方向の最大値の位置を求める

「横方向」の場合、このように各行(1次元目)ごとに最大値の位置を求めます。

横方向

各配列ごとの最大値をチェックする感じですね。

numpy 2次元配列の縦方向の最大値の位置を求める

「縦方向」の場合、各1次元目の配列ごとの、要素番号ごとの最大値の位置を求めます。

縦方向

「配列の何番目」を各配列チェックして、どれが最大値か?をチェックする感じですね。

通常の配列からnumpy配列に変換する

numpyじゃなくて普通の配列で処理を進めていた……

なんてとき、numpyさんは寛容です。

簡単にnumpyの配列に変換してくれます。

>>> arr
[[1, 6, 2, 3, 9, 5, 8, 7, 4], [9, 8, 6, 7, 5, 3, 1, 4, 2], [5, 9, 7, 8, 6, 1, 2, 3, 4]]
>>> nparr = np.array(arr)
>>> nparr
array([[1, 6, 2, 3, 9, 5, 8, 7, 4],
       [9, 8, 6, 7, 5, 3, 1, 4, 2],
       [5, 9, 7, 8, 6, 1, 2, 3, 4]])

これで実行するとこんな感じ

>>> # 縦
...
>>> np.argmax(nparr, axis=0)
array([1, 2, 2, 2, 0, 0, 0, 0, 0], dtype=int64)
>>>
>>> # 横
...
>>> np.argmax(nparr, axis=1)
array([4, 0, 1], dtype=int64)

複数の配列からnumpy 2元配列に変換する

また複数あった配列も、一旦それらを多次元配列にまとめちゃえば、そのままnumpy配列に変換できちゃいます。

>>> aa = [1,2,3]
>>> ab = [5,1,3]
>>> ac = [2,6,5]
>>> tmparr = []
>>> tmparr.append(aa)
>>> tmparr.append(ab)
>>> tmparr.append(ac)
>>> tmparr
[[1, 2, 3], [5, 1, 3], [2, 6, 5]]
>>> 
>>> nparr = np.array(tmparr)
>>> nparr
array([[1, 2, 3],
       [5, 1, 3],
       [2, 6, 5]])
>>>

これで実行するとこんな感じ

>>> # 縦
...
>>> np.argmax(nparr, axis=0)
array([1, 2, 2], dtype=int64)
>>>
>>> # 横
...
>>> np.argmax(nparr, axis=1)
array([2, 0, 1], dtype=int64)
>>>

3次元配列の場合

ぼくは今の所、2次元までしか使いませんが、試しに3次元配列も見てみましょう。

>>> nparr
array([[[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9],
        [5, 3, 1]],

       [[3, 5, 7],
        [1, 3, 9],
        [2, 7, 3],
        [8, 9, 4]]])
>>>
>>> nparr.argmax()
8
>>> np.argmax(nparr, axis=0)
array([[1, 1, 1],
       [0, 0, 1],
       [0, 0, 0],
       [1, 1, 1]], dtype=int64)
>>> np.argmax(nparr, axis=1)
array([[2, 2, 2],
       [3, 3, 1]], dtype=int64)
>>>

参考

コチラのページを参考にしました。

ありがとうございました!

deepage.net

あとがき

ディープラーニングをちょーっと齧ったお陰で、numpyを知ったのですが、知ってよかった。ほんと便利。

www.lisz-works.com

配列の処理で困ったり、簡略化したかったら、1回numpyのAPIを見てみるとイイコトあるかもしれませんね!