np.nonzero
関数は、要素が0以外のインデックスを取得するシンプルな関数です。本記事では、np.nonzero
の使い方を解説します。
np.nonzero
np.nonzero
とnp.ndarray.nonzero
の2つのタイプがあるので両方記載しておきますが、使い方はほとんど同じです。まずは、APIドキュメントからみていきましょう。
numpy.nonzero(a)
params:
パラメータ名 | 型 | 概要 |
---|---|---|
a |
array_like 配列に相当するもの |
要素の抽出を行いたい配列を指定します。 |
returns:
非ゼロ要素のあるインデックスを各軸ごとに1次元配列にして返します。
配列(ndarray)のタプル(tuple)の形で返されます。
numpy.ndarray.nonzero()
returns:
非ゼロ要素のあるインデックスを各軸ごとに1次元配列にして返します。
配列(ndarray)のタプル(tuple)の形で返されます。
np.nonzero
は配列を引数にとります。np.ndarray.nonzero
はndarrayのメソッドとして使えます。
インデックスを返してくれるので、うまく使えば非ゼロの必要な要素だけを抽出することができます。使い方を実際のコードでみていきましょう。
In [1]: import numpy as np
In [2]: a = np.random.randint(0, 10, size=20)
In [3]: a # 一次元乱数配列
Out[3]: array([0, 7, 5, 8, 4, 9, 0, 2, 1, 7, 9, 0, 6, 9, 2, 6, 0, 8, 3, 9])
In [4]: np.nonzero(a) # 非ゼロ要素のインデックスを取得
Out[4]: (array([ 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19]),)
In [5]: a.nonzero() # この書式でもOK
Out[5]: (array([ 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19]),)
In [6]: a[np.nonzero(a)] # これで非ゼロ要素抜き出した配列を生成できる。
Out[6]: array([7, 5, 8, 4, 9, 2, 1, 7, 9, 6, 9, 2, 6, 8, 3, 9])
In [10]: b = np.random.randint(0, 10, size= (4,5)) # 4×5の二次元乱数配列
In [11]: b
Out[11]:
array([[4, 2, 1, 7, 8],
[5, 5, 0, 4, 7],
[7, 6, 9, 2, 9],
[0, 1, 2, 2, 6]])
In [12]: np.nonzero(b) # 1つめの配列が行方向のインデックス、2つめの配列が列方向のインデックスになっている。
Out[12]:
(array([0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3]),
array([0, 1, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 3, 4, 1, 2, 3, 4]))
In [13]: b.nonzero()
Out[13]:
(array([0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3]),
array([0, 1, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 3, 4, 1, 2, 3, 4]))
In [14]: b[b.nonzero()] # 非ゼロ要素を抽出
Out[14]: array([4, 2, 1, 7, 8, 5, 5, 4, 7, 7, 6, 9, 2, 9, 1, 2, 2, 6])
np.where、np.argwhereとの比較
この操作はnp.where(x!=0)
で全く同じことができます。np.where
関数については、以下のリンクに詳しい解説があるので参照してみてください。
条件を満たす要素のインデックスを取得するNumPyのwhereの使い方 /features/numpy-where.html
np.where
では、3項演算子も使用できます。例えば、次のように使用することが出来ます。
In [2]: a = np.random.randint(0, 10, size=(100, 100))
In [3]: b = np.ones(shape=(100, 100))
In [4]: np.where(a != 0, a, b)
Out[4]:
array([[ 5., 3., 2., ..., 9., 9., 8.],
[ 5., 7., 1., ..., 1., 7., 5.],
[ 7., 1., 9., ..., 6., 5., 4.],
...,
[ 2., 6., 3., ..., 9., 6., 9.],
[ 4., 2., 4., ..., 7., 3., 1.],
[ 9., 4., 7., ..., 3., 6., 5.]])
np.argwhere
はインデックスの転置を返します。つまり、np.argwhere(a != 0)
はnp.transpose(np.nonzero(a))
と同義です。
In [1]: import numpy as np
In [2]: a = np.random.randint(0, 10, size=(100, 100))
In [3]: np.nonzero(a)
Out[3]: (array([ 0, 0, 0, ..., 99, 99, 99]), array([ 0, 1, 2, ..., 97, 98, 99]))
In [4]: np.where(a != 0)
Out[4]: (array([ 0, 0, 0, ..., 99, 99, 99]), array([ 0, 1, 2, ..., 97, 98, 99]))
In [5]: np.argwhere(a != 0)
Out[5]:
array([[ 0, 0],
[ 0, 1],
[ 0, 2],
...,
[99, 97],
[99, 98],
[99, 99]])
In [6]: np.transpose(np.nonzero(a))
Out[6]:
array([[ 0, 0],
[ 0, 1],
[ 0, 2],
...,
[99, 97],
[99, 98],
[99, 99]])