【NumPy】マスクした配列を扱うmaモジュール[Python]

  • URLをコピーしました!

NumPy

前回、正規化されたsinc関数を返すnp.sincを紹介しました。

今回はNumPyでマスクした配列を扱うmaモジュールを紹介します。

それでは始めていきましょう。

配列の要素にマスクするとは

まず配列の要素にマスクするとはどういうことかを解説していきます。

配列の要素のマスクする方法の一つとして「np.ma.masked_array(マスクされる配列, マスクの配列)」があります。

マスクの配列は「0」をマスクしない、「1」をマスクするで示した配列です。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

mask = [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0]

print(np.ma.masked_array(data, mask))

実行結果
[-5.0 -4.0 -- -2.0 -1.0 0.0 -- 2.0 3.0 4.0 5.0]

マスクすると指示した、つまりマスクの配列で「1」としたインデックスの要素が「–」となっています。

これがマスクされた状態です。

また配列の型は「numpy.ma.MaskedArray」という型になっています。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

mask = [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0]

print(type(np.ma.masked_array(data, mask)))

実行結果
<class 'numpy.ma.MaskedArray'>

またマスクされる要素は「fill_value=値」というオプション引数を与えると特定の値にすることができます。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

mask = [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0]

masked_array = np.ma.masked_array(data, mask)

print(np.ma.filled(masked_array, fill_value=999))

実行結果
[ -5.  -4. 999.  -2.  -1.   0. 999.   2.   3.   4.   5.]

この様な形で特定の値のみ書き換えたりすることができます。

特定の値のみマスク

ここからはいろいろなマスクの仕方を紹介していきます。

まず一つの特定の値のみマスクする方法です。

「np.ma.masked_value(配列, 値)」で指定した値のみマスクをすることができます。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

print(np.ma.masked_values(data, -3))

実行結果
[-5.0 -4.0 -- -2.0 -1.0 0.0 1.0 2.0 3.0 4.0 5.0]

また絶対許容誤差「atol」や相対許容誤差「rtol」などもオプション引数として利用することができます。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

print(np.ma.masked_values(data, 3, atol=1e-0))

実行結果
[-5.0 -4.0 -3.0 -2.0 -1.0 0.0 1.0 -- -- -- 5.0]

ただし「np.ma.masked_values」の場合は与える値は一つのみで、リストの様な形式で複数与えようとしてもエラーとなります。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

print(np.ma.masked_values(data, [-3, 1]))

実行結果
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[46], line 5
      1 import numpy as np
      3 data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]
----> 5 print(np.ma.masked_values(data, [-3, 1]))

(中略)

ValueError: operands could not be broadcast together with shapes (11,) (2,) 

また一つの値のみマスクするもう一つの方法として「np.ma.masked_equal(配列, 値)」があります。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

print(np.ma.masked_equal(data, -3))

実行結果
[-5.0 -4.0 -- -2.0 -1.0 0.0 1.0 2.0 3.0 4.0 5.0]

逆に指定した値以外の値をマスクする「np.ma.masked_not_equal(配列, 値)」というものもあります。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

print(np.ma.masked_not_equal(data, -3))

実行結果
[-- -- -3.0 -- -- -- -- -- -- -- --]

ある値より大きい、以上、より小さい、以下の値をマスク

次にある値より大きい、以上、より小さい、以下の値をマスクする方法です。

まずある値より大きい値をマスクする場合「np.ma.masked_greater(配列, 値)」を用います。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

print(np.ma.masked_greater(data, -3))

実行結果
[-5.0 -4.0 -3.0 -- -- -- -- -- -- -- --]

またある値以上の場合は「np.ma.masked_greater_equal(配列, 値)」を用います。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

print(np.ma.masked_greater_equal(data, -3))

実行結果
[-5.0 -4.0 -- -- -- -- -- -- -- -- --]

より小さい場合は「np.ma.masked_less(配列, 値)」を用います。

import numpy as np

data = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]

print(np.ma.masked_less(data, -3))

実行結果
[-- -- -3 -2 -1 0 1 2 3 4 5]

そして以下の場合は「np.ma.masked_less_equal(配列, 値)」を用います。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

print(np.ma.masked_less_equal(data, -3))

実行結果
[-- -- -- -2.0 -1.0 0.0 1.0 2.0 3.0 4.0 5.0]

ある範囲の内側、外側をマスク

ある範囲の内側の値をマスクするには「np.ma.masked_inside(配列, 値1, 値2)」を用います。

import numpy as np

data = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]

print(np.ma.masked_inside(data, -3, 2))

実行結果
[-5 -4 -- -- -- -- -- -- 3 4 5]

逆にある範囲の外側の値をマスクするには「np.ma.masked_outside(配列, 値1, 値2)」を用います。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

print(np.ma.masked_outside(data, -3, 2))

実行結果
[-- -- -3.0 -2.0 -1.0 0.0 1.0 2.0 -- -- --]

ある配列で条件に合う要素をもとに他の配列中の同じインデックスの要素をマスク

ある配列で条件に合う要素をもとに他の配列中の同じインデックスの要素をマスクするには「np.ma.masked_where(配列と条件, マスクする配列)」を用います。

import numpy as np

data1 = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]
data2 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]

print(np.ma.masked_where(np.array(data1) <= 2, data2))

実行結果
[-- -- -- -- -- -- -- -- 'i' 'j' 'k']

この例の場合、data1のうち2以下となる要素で、data2の中で同じインデックスの要素がマスクされています。

注意すべき点はマスクする条件を決める配列(上の例ではdata1)は「ndarray」である必要があります。

ちなみにマスクする条件を決める配列とマスクされる配列は同じものでも大丈夫です。

import numpy as np

data1 = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

print(np.ma.masked_where(np.array(data1) <= 2, data1))

実行結果
[-- -- -- -- -- -- -- -- 3.0 4.0 5.0]

また2つ以上の条件でマスクをしたい場合は返り値を受け取り、再度他の条件でマスクをします。

import numpy as np

data = [-5.0, -4.0, -3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0, 4.0, 5.0]

data = np.ma.masked_where(np.array(data) <= -2, data)

print(data)

data = np.ma.masked_where(np.array(data) >= 3, data)

print(data)

実行結果
[-- -- -- -- -1.0 0.0 1.0 2.0 3.0 4.0 5.0]
[-- -- -- -- -1.0 0.0 1.0 2.0 -- -- --]

次回はPandasでデータを追加する際に出るエラー「iloc cannot enlarge its target object」の対処法を紹介します。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする