1

numpy 配列に対する numpy 操作のマスクされた配列に関するドキュメントから:

numpy.ma モジュールには、ほとんどの ufunc の特定の実装が付属しています。有効領域を持つ単項関数と 2 項関数 (対数や除算など) は、入力がマスクされているか有効領域外にある場合は常に、マスクされた定数を返します。例:

ma.log([-1, 0, 1, 2])
masked_array(data = [-- -- 0.0 0.69314718056],
             mask = [ True  True False False],
       fill_value = 1e+20)

私の計算では、これらの無効な操作がどこで生成されたかを知る必要があるという問題があります。具体的には、代わりにこれが欲しいです:

ma.log([-1, 0, 1, 2])
masked_array(data = [np.nan -- 0.0 0.69314718056],
             mask = [ True  True False False],
       fill_value = 1e+20)

この質問が会話になるリスクがあるので、私の主な質問は次のとおりです。

計算された無効な値 ( np.nan や np.inf などmasked_arrayによって「修正」されたもの) がマスクされた値に変換されない (および混同されない) 場合、これを取得するための良い解決策は何ですか?fix_invalid

私の現在の解決策は、関数を計算してからmasked_array.data、マスクされた配列を元のマスクで再構築することです。ただし、ユーザーからの任意の関数を多くの異なる配列にマップするアプリケーションを作成しており、マスクされているものとされていないものがあります。マスクされた配列専用の特別なハンドラーを避けたいと考えています。さらに、これらの配列には、重要な MISSING、NaN、および Inf の区別があるため、値np.nanの代わりに s を持つ配列を使用することはできません。masked


さらに、この動作が存在する理由について何らかの見通しがある場合は、知りたいです。マスクされていない値に対する操作の結果の有効性は実際にはユーザーの責任であり、ユーザーは関数を使用して「クリーンアップ」を選択できるため、同じ操作でこれを行うのは奇妙に思えfix_invalidます。

さらに、誰かが numpy の欠損値の進行状況について何かを知っている場合は、共有してください。


編集: 2017-10-30

hpauljの答えに追加するには; 変更されたドメインを使用したログ関数の定義は、numpy 名前空間でのログの動作に副作用があります。

In [1]: import numpy as np

In [2]: np.log(np.ma.masked_array([-1,0,1,2],[1,0,0,0]))
/home/salotz/anaconda3/bin/ipython:1: RuntimeWarning: divide by zero encountered in log
  #!/home/salotz/anaconda3/bin/python
/home/salotz/anaconda3/bin/ipython:1: RuntimeWarning: invalid value encountered in log
  #!/home/salotz/anaconda3/bin/python
Out[2]: 
masked_array(data = [-- -- 0.0 0.6931471805599453],
             mask = [ True  True False False],
       fill_value = 1e+20)

In [3]: mylog = np.ma.core._MaskedUnaryOperation(np.core.umath.log)

In [4]: np.log(np.ma.masked_array([-1,0,1,2],[1,0,0,0]))
/home/salotz/anaconda3/bin/ipython:1: RuntimeWarning: divide by zero encountered in log
  #!/home/salotz/anaconda3/bin/python
/home/salotz/anaconda3/bin/ipython:1: RuntimeWarning: invalid value encountered in log
  #!/home/salotz/anaconda3/bin/python
Out[4]: 
masked_array(data = [-- -inf 0.0 0.6931471805599453],
             mask = [ True False False False],
       fill_value = 1e+20)

np.logは と同じ動作をするようになりましmylognp.ma.logが、変更はありません。

In [5]: np.ma.log(np.ma.masked_array([-1,0,1,2],[1,0,0,0]))
Out[5]: 
masked_array(data = [-- -- 0.0 0.6931471805599453],
             mask = [ True  True False False],
       fill_value = 1e+20)

これを回避する方法はありますか?

使用Python 3.6.2 :: Anaconda custom (64-bit)してnumpy1.12.1

4

1 に答える 1

3

ここで何が起こっているように見えるかを明確にしてください

np.ma.log引数で実行np.logされますが、警告がトラップされます。

In [26]: np.log([-1,0,1,2])
/usr/local/bin/ipython3:1: RuntimeWarning: divide by zero encountered in log
  #!/usr/bin/python3
/usr/local/bin/ipython3:1: RuntimeWarning: invalid value encountered in log
  #!/usr/bin/python3
Out[26]: array([        nan,        -inf,  0.        ,  0.69314718])

nanとの値をマスクし-infます。そして明らかに元の値をこれらのdataスロットにコピーします:

In [27]: np.ma.log([-1,0,1,2])
Out[27]: 
masked_array(data = [-- -- 0.0 0.6931471805599453],
             mask = [ True  True False False],
       fill_value = 1e+20)
In [28]: _.data
Out[28]: array([-1.        ,  0.        ,  0.        ,  0.69314718])

(Py3 で実行; numpy バ​​ージョン 1.13.1)

このマスキング動作は に固有のものではありませんma.log。それはそのクラスによって決定されます

In [41]: type(np.ma.log)
Out[41]: numpy.ma.core._MaskedUnaryOperation

と属性np.ma.coreで定義されています。filldomain

log = _MaskedUnaryOperation(umath.log, 1.0,
                        _DomainGreater(0.0))

したがって、有効なドメイン (マスクされていない) は >0 です。

In [47]: np.ma.log.domain([-1,0,1,2])
Out[47]: array([ True,  True, False, False], dtype=bool)

そのドメインマスクor-ed

In [54]: ~np.isfinite(np.log([-1,0,1,2]))
...
Out[54]: array([ True,  True, False, False], dtype=bool)

これは同じ値を持っています。

log独自のドメイン マスキングを追加しないカスタムを定義できるようです。

In [58]: mylog = np.ma.core._MaskedUnaryOperation(np.core.umath.log)
In [59]: mylog([-1,0,1,2])
Out[59]: 
masked_array(data = [        nan        -inf  0.          0.69314718],
             mask = False,
       fill_value = 1e+20)

In [63]: np.ma.masked_array([-1,0,1,2],[1,0,0,0])
Out[63]: 
masked_array(data = [-- 0 1 2],
             mask = [ True False False False],
       fill_value = 999999)
In [64]: np.ma.log(np.ma.masked_array([-1,0,1,2],[1,0,0,0]))
Out[64]: 
masked_array(data = [-- -- 0.0 0.6931471805599453],
             mask = [ True  True False False],
       fill_value = 1e+20)
In [65]: mylog(np.ma.masked_array([-1,0,1,2],[1,0,0,0]))
Out[65]: 
masked_array(data = [-- -inf 0.0 0.6931471805599453],
             mask = [ True False False False],
       fill_value = 1e+20)
于 2017-10-27T21:06:23.170 に答える