LoginSignup
0
2

More than 1 year has passed since last update.

NumPy で欠損値等を除く時は np.ma.masked_where が便利

Posted at

要素削除の問題点

NumPyで欠損値や外れ値を除く時どうしてますか?多くの人が単純にその要素を配列から削除していると思います。例えばnanを除くなら以下のような感じ。

これでもいいが...
a = np.array([3, 4, np.nan, 8, np.nan])
a = a[~np.isnan(a)]
print(a) # [3. 4. 8.]
print(a.mean()) # 5.0

この方法でもいいのですが、よくある問題として要素を削除するとそれが元のデータの何番目だったのか分からなくなるということがあります。例えば値を除いて分析した後にこの最大値を取るものを個別に見てみたいとか思っても、消している要素があるのでそれが元のデータ上では何番目になるのかわかりません。

Masked Array

そんな時に便利なのがmasked arrayです。masked arrayはNumPyに元から入っている機能です。masked arrayは普通のndarrayとマスクを一つにした型で、個々の要素についてマスクするかしないかを決められます。そしてマスクした要素はndarrayに存在はしますが、あらゆる計算から除外されます。

例えば上の例をmasked arrayを使って書き直したのが以下です。

maske arrayを使う
a = np.array([3, 4, np.nan, 8, np.nan])
print(a.mean()) # nan
a = np.ma.masked_where(np.isnan(a), a)
print(a) # [3.0 4.0 -- 8.0 --]
print(a.mean()) # 5.0

np.ma.masked_where関数でmasked arrayを作っています。第一引数がマスクのbool型ndarray、第二引数がマスクされる元のndarrayです。上記のようにmasked arrayではマスクされた要素は--で表されており、a.mean()では計算から外されています.

Masked arrayでは要素を消している訳ではないので加工前と後の対応関係がわからなくなるということがありません。

もっと例を見る

行列で-1を含む行全体をマスクしたい時。

a = np.array([
    [0, 1, -1],
    [3, 3, 9],
    [1, 4, 6],
    [-1, 5, -1],
])
a = np.ma.mask_rows(np.ma.masked_where(a == -1, a))
print(a)
# [[-- -- --]
#  [3 3 9]
#  [1 4 6]
#  [-- -- --]]
print(a.sum(axis=1)) # [-- 15 11 --]

Masked arrayのスカラー倍は同じ場所がマスクされたmasked arrayを返す。行列積はエラーになる模様(正確なマスク伝搬の仕組みは理解してない...)。

a = np.ma.masked_where([False, True, False, True], [0, 1, 2, 3])
print(2 * a) # [0 -- 4 --]
print(a @ np.array([[1], [1], [1], [1]])) # ValueError: could not broadcast where mask from shape (4,4) into shape (1,)

naninfを両方マスクしたいとき、np.ma.masked_invalid関数がショートカットとして使える。

a = np.array([ 0,  1, np.nan, np.inf, -np.inf])
print(np.ma.masked_invalid(a)) # [0.0 1.0 -- -- --]

あとがき

masked arrayはNumPy標準の機能なのに知名度が低いと思います。まあ私も何番目か分からなくなるのを防ぐ以外のメリットが思いつかないので、利用価値が低いのでしょう。でもこの機能があること知っていればそのような特定の場面でとても便利に使えると思います。

参考

https://numpy.org/doc/stable/reference/maskedarray.html

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2