NumPyで最小値を取得するamin(), nanmin()関数とmin()メソッドの使い方

NumPyには配列の最小値を取得するための関数であるnp.amin()と、メソッドであるndarray.min()が用意されています。

np.amin()ndarray.min() は、前者が関数で後者がメソッドという点を除いて全く同じです。関数の場合は np.amin(a) というように引数に対象となる配列を渡しますが、メソッドの場合は a.min() というように対象となる配列の後ろに繋げて書きます。

これらに加えて、np.nanmin()という関数もあります。これも、np.amin()と同じですが、欠損値nanに対する扱いが異なります。np.amin()は対象となる配列に欠損値nanが含まれる場合、nanを返します。一方で、np.nanmin()は欠損値nanを無視して最小値を返します。

まとめると次のようになります。

  • np.amin: 配列内の最小値を取得する関数(nan優先)
  • np.nanmin: 配列内の最小値を取得する関数(nan無視)
  • ndarray.min: 配列内の最小値を取得するメソッド

このページでは、これらの関数について解説します。

NumPy配列の最小値の操作まとめ
NumPy配列の最小値を操作する全方法については、『NumPy配列の最小値やそのインデックスを取得する関数・メソッドまとめ』ですべてまとめています。ぜひ一度ご確認ください。

目次

1. 書式

まずは書式を確認しておきましょう。np.amin()np.nanmin()は全く同じなので、ここではnp.amin()のみ記しておきます。

なお、これから見ていく通り、この関数には多くのオプション引数があります。ただし、実際によく使うのは axis ぐらいです。その次に使う可能性があるのは、keepdims, initial です。そのため、この3つを抑えておくようにすると良いでしょう。

numpy.amin関数

書き方:

np.amin(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になります。

一緒に確認したい関数:

  • amax: 最大値を取得
  • nanmin配列の指定の軸方向の要素のうち最小値を返す。欠損値NaNは無視。当ページ内で解説
  • minimum2つの配列の各要素のうち値が小さい方を返す。欠損値NaN優先。
  • fmin同上。欠損値NaNは無視。上と同じページで解説。
  • argmin配列の指定の軸方向の要素の最小値のインダイスを返す。
  • nanmax, maximum, fmax
ndarray.minメソッド

書き方:

ndarray.min(axis=None, out=None, keepdims=<no value>, initial=<no value>, where=<no value>)

2. サンプルコード

それでは実際にサンプルコードを見て確認していきましょう。

なお、上述の通りnp.amin()np.nanmin()は欠損値の扱いを除いて全く同じです。ndarray.min()np.amin()と同じですが、メソッドであるため、a.min()というように対象となる配列を前に書きます。

すべてを同じように解説すると煩雑になるため、ここからはnp.amin()をメインに解説を進めていきます。

1次元配列の最小値を取得

対象となる配列a が1次元配列の場合、np.amin()は、その中の最小値を返します。

以下の配列を例に見てみましょう。

In [1]:
import numpy as np
rng = np.random.default_rng()
a = rng.integers(-10, 11, (5, ))
a
Out[1]:
array([  7,  -7, -10,  -3,  -1])

この配列a をnp.amin()に渡すと、最小値を返します。

In [2]:
# 最小値を返す
np.amin(a)
Out[2]:
-10

ndarray.min()メソッドの場合は次のように書きます。

In [3]:
# メソッドの場合
a.min()
Out[3]:
-10

配列の中に欠損値nanがある場合は、np.amin()ndarray.min()はnanを返します。

In [1]:
import numpy as np
a = np.array([  7,  -7, -10,  -3,  -1, np.nan])
a
Out[1]:
array([  7.,  -7., -10.,  -3.,  -1.,  nan])
In [2]:
# 欠損値nanがある場合はnanを返す。
np.amin(a)
Out[2]:
nan
In [3]:
# メソッドも同様にnanを返す。  
a.min()
Out[3]:
nan

ただし、np.nanmim()は欠損値nanを無視して最小値を返します。これらの違いを覚えておいて使い分けられるようにしましょう。

In [4]:
#  np.nanmin()関数はnanを無視して最小値を返す。
np.nanmin(a)
Out[4]:
-10.0

多次元配列の最小値を取得

多次元配列の場合も、デフォルトでは、全要素の中から最小値を返します。以下の配列を例に見ていきましょう。

In [1]:
import numpy as np
rng = np.random.default_rng()
a = rng.integers(-10, 11, (3, 5))
a
Out[1]:
array([[  6,  -9,   4,  -2,  -9],
       [-10,  -7,  -2,   4,  10],
       [ -5,  -7,   5,  -6,   2]])

以下のように、デフォルトでは次元軸に関わらず、全要素の中の最小値を返します。

In [2]:
# デフォルトでは全要素のうち最小値を返す。
np.amin(a)
Out[2]:
-10
In [3]:
# メソッドも同じ
a.min()
Out[3]:
-10

次元軸を指定して最小値を取得

オプション引数 axis で、最小値を求める次元軸を指定することができます。

1次元軸を指定した場合は、各行の中の最小値を返します。

In [4]:
# 1次元軸(横軸)を指定
np.amin(a, axis=-1)
Out[4]:
array([ -9, -10,  -7])

2次元軸を指定した場合は、各列の中の最小値を返します。

In [5]:
# 2次元軸(縦軸)を指定
np.amin(a, axis=0)
Out[5]:
array([-10,  -9,  -2,  -6,  -9])

ndarray.min()メソッドでも同じです。

In [6]:
# メソッドも同じ
a.min(axis=-1)
Out[6]:
array([ -9, -10,  -7])
In [7]:
a.min(axis=0)
Out[7]:
array([-10,  -9,  -2,  -6,  -9])

重要: np.minimum()を使うべきケース

多次元配列で最初の軸の要素数が2の場合、つまり2次元配列なら shape(2, n)、3次元配列ならshape(2, n, k)の場合、で最初の軸(axis=0)の最小値を取得する場合は、np.amin()よりもnp.minimum()の方が高速です。

以下の一連のコードをご覧ください。

In [1]:
# 最初の軸(axis=0)の要素数が2の配列を作成
import numpy as np
rng = np.random.default_rng()
a = rng.integers(-10, 11, (2, 5))
a
Out[1]:
array([[-5, -5,  8, -6, -7],
       [ 2,  8, -2,  4,  5]])
In [2]:
# この場合はnp.aminよりもnp.minimumの方が遥かに高速
np.amin(a, axis=0)
Out[2]:
array([-5, -5, -2, -6, -7])
In [3]:
np.minimum(a[0], a[1])
Out[3]:
array([-5, -5, -2, -6, -7])

この場合、np.minimum()の方が遥かに高速です。

実際に処理時間を計測してみましょう。

In [4]:
%%timeit
np.amin(a, axis=0)
4 µs ± 49.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [5]:
%%timeit
np.minimum(a[0], a[1])
885 ns ± 4.79 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

このように、両者の間には5倍近い速度差があります。小ネタですが少しでも高速にしたい場合のTIPSとして覚えておくと良いでしょう。

元の配列の次元数を維持して最小値を取得

オプション引数で keepdims=True にすると、元の配列の次元数を維持したまま最小値を出力してくれます。つまり、元の配列とブロードキャスト可能な形状になります。

以下の一連のコードでご確認ください。

In [1]:
import numpy as np
rng = np.random.default_rng()
a = rng.integers(-10, 11, (3, 5))
a
Out[1]:
array([[-10,   0,  -9,   6,   1],
       [  2,   4,   1,  10,   0],
       [ -2,   8,   2,   9,  -9]])
In [2]:
# 次元数を維持
np.amin(a, axis=-1, keepdims=True)
Out[2]:
array([[-10],
       [  0],
       [ -9]])
In [3]:
np.amin(a, axis=0, keepdims=True)
Out[3]:
array([[-10,   0,  -9,   6,  -9]])
In [4]:
# メソッドでも同じ
a.min(axis=-1, keepdims=True)
Out[4]:
array([[-10],
       [  0],
       [ -9]])
In [5]:
a.min(axis=0, keepdims=True)
Out[5]:
array([[-10,   0,  -9,   6,  -9]])

任意の最小値を指定

オプション引数のinitialを使うと、配列内に指定した値よりも小さな値がない場合は、この値を返すようになります。

以下の一連のコードでご確認ください。

In [1]:
import numpy as np
rng = np.random.default_rng()
a = rng.integers(0, 11, (5, ))
a
Out[1]:
array([0, 1, 7, 7, 5])
In [2]:
np.amin(a, initial=-10)
Out[2]:
-10
In [3]:
# メソッドでも同じ
a.min(initial=-10)
Out[3]:
-10

なお、NumPyのamin()のオプション引数initialと、Python組み込み関数のmin()のオプション引数dfaultで混同されやすい点があります。

Pythonの組み込み関数min()のオプション引数defaultは、関数に渡した配列の要素が空の時に返す値です。一方で、np.amin()のオプション引数initialは、配列の中に指定した値より小さな値がない場合に、指定の値を返します。

この点を混同のないように覚えておきましょう。

3. まとめ

以上が、np.amin()ndarray.min()np.nanmin()それぞれの使い方です。

冒頭でも述べましたが、それぞれの使い分け方は以下の通りです。

  • np.amin: 配列内の最小値を取得する関数(nan優先)
  • np.nanmin: 配列内の最小値を取得する関数(nan無視)
  • ndarray.min: 配列内の最小値を取得するメソッド

ぜひ、参考にして頂ければと思います。



よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

目次
閉じる