NumPyのargwhere()関数は、① 0以外の要素のインダイスを要素ごとに取得します。または、② 指定の条件に合致する要素のインダイスを要素ごとに取得します。
①と同じ働きをする関数には、ほかにnumpy.nonzero()もあります。しかし、こちらは0以外の要素のインダイスを次元軸ごとに取得します。結論から言えば、配列の高度なスライスを行うにはnumpy.nonzero()の方が適しています。
②についても、指定の条件に合致する要素を操作するには、numpy.where()関数の方が適しています。
そのため、numpy.argwhere()の使用頻度は高くありません。このページでは、上述の関数も含めて簡潔に解説していきます。
配列の高度なスライスについて
NumPy配列のスライシングのテクニックについては『NumPyの配列のスライスの必須テクニックまとめ』でまとめています。こちらも確認いただくことで、スキルや理解を深めることにつながります。
NumPy配列の条件を満たす要素の操作まとめ
NumPy配列では、条件を満たす要素の値を取得したり、数をカウントしたり、置換したりなど様々な操作が可能です。こうした操作については、『NumPy配列の条件を満たす要素の確認や置換・カウントの方法まとめ』で全てまとめていますので、ぜひご確認ください。
1. numpy.argwhereの使い方
まずは書式を確認しましょう。とは言っても、この関数にはオプション引数はありません。
Note
np.argwhere(a)は、np.transpose(np.nonzero(a))とほとんど同じです。しかし、こちらの方が0次元の配列(要素が1つの配列:スカラー)に対しても正しく機能します。ただし、配列のスライシングにおいては、argwhere()で取得するインダイスよりもnonzero()で取得するインダイスの方が適しています。
2. サンプルコード
それではサンプルコードを確認しましょう。
まずは以下の2次元配列a を作成します。
import numpy as np
a = np.array([[3, 0, 0], [0, 4, 0], [5, 6, 0]])
a
この配列をnumpy.argwhere()に渡すと、値が0以外の要素のインダイスをインダイスごとに返します。
# 値が0以外の要素のインダイスを要素ごとに取得
np.argwhere(a)
このインダイスを使って値を取り出してみましょう。
# 要素の取得
for i in np.argwhere(a):
print(a[tuple(i)])
なお、配列のスライスにはnumpy.nonzero()の方が遥かに適しています。この関数は、以下のコードのように、0以外の要素のインダイスを次元軸区切りで取得します。
# 配列のスライシングにはnp.nonzero()の方が適しています
ind = np.nonzero(a)
ind
この形のインダイスであれば、直接、配列をスライスすることで値を取得することができます。
a[ind]
このため、配列のスライス目的でのインダイスの取得ならば、numpy.nonzero()を使います。
一方で、numpy.argwhere()の利点は条件式定義の自由度にあります。numpy.nonzero()は0以外の要素のインダイスしか取得できませんが、numpy.argwhere()は条件式を書くことで、様々な値のインダイスを取得することが可能です。
# np.argwhere()の利点は条件式定義の自由度にあります
np.argwhere(a >= 5 )
なお、条件に合う要素、合わない要素を任意の値に置換したい場合は、numpy.where()を使います。
# 条件に合う要素を100に、合わない要素を0に置換
np.where(a>=5, 100, 0)
3. まとめ
以上がnumpy.argwhere()の使い方です。
コメント