NumPyには配列の最大値を取得するための関数であるnp.amax()と、メソッドであるndarray.max()が用意されています。
np.amax() とndarray.max() は、前者が関数で後者がメソッドという点を除いて全く同じです。関数の場合は np.amax(a) というように引数に対象となる配列を渡しますが、メソッドの場合は a.max() というように対象となる配列の後ろに繋げて書きます。
これらに加えて、np.nanmax()という関数もあります。これも、np.amax()と同じですが、欠損値nanに対する扱いが異なります。np.amax()は対象となる配列に欠損値nanが含まれる場合、nanを返します。一方で、np.nanmax()は欠損値nanを無視して最小値を返します。
まとめると次のようになります。
- np.amax: 配列内の最大値を取得する関数(nan優先)
- np.nanmax: 配列内の最大値を取得する関数(nan無視)
- ndarray.max: 配列内の最大値を取得するメソッド
このページでは、これらの関数について解説します。
NumPy配列の最大値の操作まとめ
NumPy配列の最大値を操作する全方法については、『NumPy配列の最大値やそのインデックスを取得する関数とメソッドまとめ』ですべてまとめています。ぜひ一度ご確認ください。
1. 書式
まずは書式を確認しておきましょう。np.amax()とnp.nanmax()は全く同じなので、ここではnp.amax()のみ記しておきます。
なお、これから見ていく通り、この関数には多くのオプション引数があります。ただし、実際によく使うのは axis ぐらいです。その次に使う可能性があるのは、keepdims, initial です。そのため、この3つを抑えておくようにすると良いでしょう。
書き方:
np.amax(a, axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)
パラメーター:
引数 | 型 | 解説 |
---|---|---|
a | array_like | 最大値を求める対象である配列を渡します。 |
axis* | None or int or tuple of ints | a が多次元配列の場合、どの次元軸の最大値を求めるかを指定します。 |
out* | ndarray | ここで指定した配列を、関数の戻り値で上書きします。双方の配列のshapeが一致している必要があります。 |
keepdims* | bool | これをTrueに指定すると、元の配列の次元数を維持します。ブロードキャストに便利です。 |
initial* | scalar | ここで指定した値より大きな値がない場合は、この値を返します。 |
where* | array_like of bool | 要素がブール値の配列を渡すと、Trueに該当する要素のみを対象としてその中の最大値を返します。 |
* はオプション引数であることを示します。 |
戻り値:
最大値を要素とする配列またはスカラー 配列aの最大値を求めます。axis=Noneの時は、スカラー(要素が1つの配列)が生成されます。axisを指定した時は、生成される配列の次元数は元の配列の次元数-1になります。 |
一緒に確認したい関数:
書き方:
ndarray.max(axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)
2. サンプルコード
それでは実際にサンプルコードを見て確認していきましょう。
なお、上述の通りnp.amax()とnp.nanmax()は欠損値の扱いを除いて全く同じです。ndarray.max()もnp.amax()と同じですが、メソッドであるため、a.max()というように対象となる配列を前に書きます。
すべてを同じように解説すると煩雑になるため、ここからはnp.amax()をメインに解説を進めていきます。
1次元配列の最大値
対象となる配列a が1次元配列の場合、np.amax()は、その中の最大値を返します。
以下の配列を例に見てみましょう。
import numpy as np
rng = np.random.default_rng()
a = rng.integers(-10, 11, (5, ))
a
この配列a をnp.amax()に渡すと、最大値を返します。
# 最大値を返す
np.amax(a)
ndarray.max()メソッドの場合は次のように書きます。
# メソッドの場合
a.max()
配列の中に欠損値nanがある場合は、np.amax()とndarray.max()はnanを返します。
import numpy as np
a = np.array([ 7, 1, -10, -3, 5, np.nan])
a
# 欠損値nanがある場合はnanを返す。
np.amax(a)
# メソッドも同様にnanを返す。
a.max()
ただし、np.nanmax()は欠損値nanを無視して最大値を返します。これらの違いを覚えておいて使い分けられるようにしましょう。
# np.nanmax()関数はnanを無視して最大値を返す。
np.nanmax(a)
多次元配列の最大値を取得
多次元配列の場合も、デフォルトでは、全要素の中から最大値を返します。以下の配列を例に見ていきましょう。
import numpy as np
rng = np.random.default_rng()
a = rng.integers(-10, 11, (3, 5))
a
以下のように、デフォルトでは次元数に関わらず、全要素の中の最大値を返します。
# デフォルトでは全要素のうち最大値を返す。
np.amax(a)
# メソッドも同じ
a.max()
次元軸を指定して最大値を取得
オプション引数 axis で、最大値を求める次元軸を指定することができます。1次元軸を指定した場合は、各行の中の最大値を返します。
# 1次元軸(横軸)を指定
np.amax(a, axis=-1)
2次元軸を指定した場合は、各列の中の最大値を返します。
# 2次元軸(縦軸)を指定
np.amax(a, axis=0)
ndarray.max()メソッドでも同じです。
# メソッドも同じ
a.max(axis=-1)
a.max(axis=0)
重要: np.maximum()を使うべきケース
多次元配列で最初の軸の要素数が2の場合、つまり2次元配列なら shape(2, n)、3次元配列ならshape(2, n, k)の場合、で最初の軸(axis=0)の最大値を取得する場合は、np.amax()よりもnp.maximum()の方が高速です。
以下の一連のコードをご覧ください。
# 最初の軸(axis=0)の要素数が2の配列を作成
import numpy as np
rng = np.random.default_rng()
a = rng.integers(-10, 11, (2, 3, 4))
a
# この場合はnp.amaxよりもnp.maximumの方が遥かに高速
np.amax(a, axis=0)
np.maximum(a[0], a[1])
この場合、出力結果は同じですが np.maximum()の方が遥かに高速です。実際に処理時間を計測してみましょう。
%%timeit
np.amax(a, axis=0)
%%timeit
np.maximum(a[0], a[1])
このように、両者の間には5倍近い速度差があります。この点は、ぜひ覚えておきましょう。
元の配列の次元数を維持して最小値を取得
オプション引数で keepdims=True にすると、元の配列の次元数を維持したまま最大値を出力してくれます。つまり、元の配列とブロードキャスト可能な形状になります。
以下の一連のコードでご確認ください。
import numpy as np
rng = np.random.default_rng()
a = rng.integers(-10, 11, (3, 5))
a
# 次元数を維持
np.amax(a, axis=-1, keepdims=True)
np.amax(a, axis=0, keepdims=True)
# メソッドでも同じ
a.max(axis=-1, keepdims=True)
a.max(axis=0, keepdims=True)
任意の最大値を指定
オプション引数のinitialを使うと、指定した値よりも大きな値が配列内にない場合は、この値を返すようになります。
以下の一連のコードでご確認ください。
import numpy as np
rng = np.random.default_rng()
a = rng.integers(-10, 1, (5, ))
a
np.amax(a, initial=10)
# メソッドでも同じ
a.max(initial=10)
なお、NumPyのamax()のオプション引数initialと、Python組み込み関数のmax()のオプション引数dfaultで混同されやすい点があります。
Pythonの組み込み関数max()のオプション引数defaultは、関数に渡した配列の要素が空の時に返す値です。一方で、np.amax()のオプション引数initialは、配列の中に指定した値より大きな値がない場合に、指定の値を返します。
この点を混同のないように覚えておきましょう。
3. まとめ
以上が、np.amax()とndarray.max()、np.nanmax()それぞれの使い方です。
冒頭でも述べましたが、それぞれの使い分け方は以下の通りです。
- np.amax: 配列内の最大値を取得する関数(nan優先)
- np.nanmax: 配列内の最大値を取得する関数(nan無視)
- ndarray.max: 配列内の最大値を取得するメソッド
ぜひ参考にして頂ければ幸いです。
コメント