NumPy配列のブールインデックス参照 2015/07/19
[]
の中にインデックスを書く代わりに論理値(True
/False
)の配列を書くとその論理値がTrue
に該当する箇所の要素をピックアップしたndarrayを新しく作ってくれる。
ndarr1 = np.array([0, 10, 20, 30, 40, 50])
print(ndarr1)
# 出力結果
# [ 0 10 20 30 40 50]
print(ndarr1[np.array([False, True, False, False, False, True])])
# 出力結果
# [10 50]
これの何が便利かというと、まず ndarr1 % 20 == 0
のように書くと
ベクトル計算により論理値の配列が生成されるので、それをそのまま []
の中に書くことによってフィルタ処理のようなことができるのである。
print(ndarr1 % 20 == 0)
# 出力結果
# [ True False True False True False]
print(ndarr1[ndarr1 % 20 == 0])
# 出力結果
# [ 0 20 40]
論理値の配列同士で論理和演算子 |
、論理積演算子 &
も使える。
print(ndarr1[(ndarr1 % 20 == 0) | (ndarr1 % 30 == 0)])
# 出力結果
# [ 0 20 30 40]
print(ndarr1[(ndarr1 % 20 == 0) & (ndarr1 % 30 == 0)])
# 出力結果
# [0]
[]
に論理型のndarrayではなく普通の配列を渡すと意図した動作にならない。将来のバージョンでは変わるかもしれないが、自分が試した Python 2.7.8, NumPy 1.9.0 の環境ではダメだった。
print(ndarr1[[False, True, False, False, False, True]])
# 出力結果
# FutureWarning: in the future, boolean array-likes will be handled as a boolean array index
# [ 0 10 0 0 0 10]
ブールインデックスで得た配列はもとの配列から必要な要素をコピーして作成される新しい配列であって、従って新しい配列を書き換えても、もとの配列には影響しない。
bi = ndarr1[ndarr1 % 20 == 0]
print(bi)
# 出力結果
# [ 0 20 40]
bi[0] = 100
print(bi)
# 出力結果
# [100 20 40]
print(ndarr1)
# 出力結果
# [ 0 10 20 30 40 50]
参照だけでなく、代入もできる。ブールインデックスでの代入は複数の要素をまとめて書き換えることができる。
ndarr1[ndarr1 % 20 == 0] = [100, 120, 140]
print(ndarr1)
# 出力結果
# [100 10 120 30 140 50]
ブールインデックスに配列ではなく数値を代入すると、ブールインデックスで参照されている要素にすべて同一の値が代入される。
ndarr1[ndarr1 % 20 == 0] = 1000
print(ndarr1)
# 出力結果
# [1000 10 1000 30 1000 50]
関連