ndarrayの要素を条件に応じて置き換える【Python】

ndarrayの要素を条件に応じて置き換える関数としてはwhere関数、putmask関数、place関数などがあります。それぞれ同じようなことができますが、微妙に使い方や働きが違うので、ここではその使い分けを見ていきましょう。

開発環境

  • numpy 1.19.2
  • Python 3.7.9

ndarrayの要素を条件に従って置き換える関数

ndarrayの配列要素を条件式に従って置き換える関数には次のようなものがあります。

where関数は条件を満たす要素と満たさない要素の両方とも指定した値に置き換えた新たな配列を生成して返すのに対して、putmask関数とplace関数は引数で指定された配列の値を書き換えます(新たな配列を生成するのではなく、元の配列の値を書き換えます)。なお、putmask関数とplace関数では、条件を満たすものを置き換える際の値の指定方法によってその動きに差があります。

それでは順番にその使い方を見ていきましょう。

where関数の使い方

where関数

where関数は、第1引数(condition引数)に条件を表す配列として「True / False」から成るbool値の配列を指定し、第2引数(x引数)・第3引数(y引数)にそれぞれx、yを指定することで、Trueの要素をxに、Falseの要素をyとした新しいndarray配列を返します。

ここでcondition引数にndarrayを用いた条件式を指定することで、自動的にその条件式をブロードキャストしてくれてbool値の配列として取得することができます。そのためcondition引数に指定するのは「a >= 5」のようなシンプルな条件式で構いません。

import numpy as np
 
a = np.array([1, 3, 2, 4, 7, 5, 6, 10, 8, 9])
print(np.where(a >= 5, 1, 0))
[0 0 0 0 1 1 1 1 1 1]

ここでは4行目で、配列aの要素のうち5以上のものを1として、5未満のものを0とした新たな配列を生成して出力しています。この関数は次のように「条件を満たすものをTrueに、満たさないものをFalseにする」ような場合にも使えます。

import numpy as np
 
a = np.array([1, 3, 2, 4, 7, 5, 6, 10, 8, 9])
print(np.where(a >= 5, True, False))
[False False False False  True  True  True  True  True  True]

また、x引数、y引数に元の配列を用いた関係式を指定することで、元の配列の値をもとにした値に置き換えることが可能です。

import numpy as np
 
a = np.array([1, 3, 2, 4, 7, 5, 6, 10, 8, 9])
print(np.where(a >= 5, a*100, a))
[   1    3    2    4  700  500  600 1000  800  900]

ここでは5以上という条件を満たすものの値を100倍にしています。

where関数のもう1つの使い方:条件を満たすもののインデックスを取得する

先ほどはwhere関数の値を条件式に従って置き換えましたが、where関数のcondition引数のみを指定した場合は、conditionを満たすも要素のインデックスが配列で返されます。例えば以下のような場合を見てみましょう。

import numpy as np
 
a = np.array([1, 3, 2, 4, 7, 5, 6, 10, 8, 9])
print(np.where(a >= 5))
(array([4, 5, 6, 7, 8, 9], dtype=int64),)

4行目ではwhere関数にcondition引数のみ指定していて、そうするとその条件を満たす要素のインデックスだけ返されます。ここでは5以上の要素は5-10番目の要素なので、0から始まるインデックスで4-9が返されています。

putmask関数とplace関数の使い方

putmask関数

putmask関数は第1引数(a引数)に操作する配列を指定し、第2引数(mask引数)に条件を、第3引数(values引数)に条件を満たすものを置き換える値を指定します。なお、条件の指定方法はbool値の配列として指定しますが、where関数の場合と同様にndarrayを用いた条件式で指定すれば自動的にbool値の配列となります。置き換え値はvalues引数に指定した配列から、置き換えるa引数の値に対応するインデックスのものが選択されます。なお、values引数のサイズが小さい場合は配列が繰り返されてサイズが調整されます。

place関数

place関数は第1引数(arr引数)に操作する配列を指定し、第2引数(mask引数)に条件を、第3引数(vals引数)に条件を満たすものを置き換える値を指定します。なお、条件の指定方法はbool値の配列として指定しますが、where関数の場合と同様にndarrayを用いた条件式で指定すれば自動的にbool値の配列となります。vals引数に配列で値を指定すると、その配列の最初から置き換える値として設定されます。

putmask関数とplace関数の違い

putmask関数とplace関数の使い分けは、置き換える値の指定方法にあります。元のputmask関数では置き換え対象(a引数)のndarrayと同じサイズのndarrayが置き換え値(values引数)に指定されていると、対応するインデックスの値に置き換えられますが、place関数の場合はそのインデックスには関係なく置き換え値(vals引数)の値が最初から順番に選択されて置き換えられていきます。

import numpy as np
 
a1 = np.array([1, 3, 2, 4, 7, 5, 6, 10, 8, 9])
a2 = np.array([1, 3, 2, 4, 7, 5, 6, 10, 8, 9])

np.putmask(a1, a1>=5, a1*100)
print(a1)

np.place(a2, a2>=5, a2*100)
print(a2)
[   1    3    2    4  700  500  600 1000  800  900]
[  1   3   2   4 100 300 200 400 700 500]

この例では、putmask関数とplace関数と双方ともに置き換え値として元の配列を100倍したものが指定されています。5以上の値は5番目以降の要素なので、putmask関数ではa1の5倍目以降の値が100倍されて置き換えられていますが、place関数では対応するインデックスは特に考慮されないのでa2の1番目から100倍されて置き換えられています。

なおこのとき、putmask関数とplace関数の引数に入れられたa1とa2は、それ自体の値が書き換えられていることに注意してください。これに対してwhere関数は引数に指定した配列自体には手を加えずに、新たな配列を生成するだけという点も大きな特徴です。

関連記事・スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)