2010-12-19 16 views
15

私はnumpyでログを取って、ログを取る前に負であったエントリを無視したいと思います。負のエントリのログをとると、-Infが返されるので、-Infの値を持つ行列が結果として得られます。私はこの行列の列を合計したいのですが、-Infの値を無視して、どうすればいいのですか?例えばPythonでnumpy/scipyを使用している配列の-Inf値を無視する

mylogarray = log(myarray) 
# take sum, but ignore -Inf? 
sum(mylogarray, 0) 

私はnansumがあります知っていると私は同等、infsumようなものが必要。

ありがとうございました。

答えて

10

使用masked arrays

>>> a = numpy.array([2, 0, 1.5, -3]) 
>>> b = numpy.ma.log(a) 
>>> b 
masked_array(data = [0.69314718056 -- 0.405465108108 --], 
      mask = [False True False True], 
     fill_value = 1e+20) 

>>> b.sum() 
1.0986122886681096 
+1

これを拡張していただけますか?私はその例を理解していない。上記のマスクされた配列をどのように初期化しましたか? – user248237dfsf

+3

@ user248237 - 'numpy.ma.log'などの関数は、自動的にマスクされた配列を作成し、' inf'または 'nan'をマスクするものはマスクされます。しかしこれはあまり明白ではないので、代わりに 'a = np.ma.masked_where(a == np.inf、a)'を実行し、 'b = np.log(a)'を実行するだけです。 (または他の任意の機能)。あるいは、マスクされた配列を避けて 'np.log(a [a!= np.inf])。sum()'を実行することもできます(ブール値配列で索引付けすることができます。 –

+0

@ user248237マスクされた配列を明示的に初期化しませんでした。 'a'は通常のマスクされていない配列です。 'ma.log'は、(実数)対数が未定義のすべての値をマスクします。次に、マスクされたエントリbがマスクされていない場合と同様に、結果のマスクされた配列bが処理されます。 – Philipp

1

filter()を使用します。

>>> array 
array([ 1., 2., 3., -Inf]) 
>>> sum(filter(lambda x: x != float('-inf'), array)) 
6.0 
+0

これはベクトル化された操作と見なされますか?より効率的な方法がありますか?私はコード内でこれを何度もやり直す必要があり、ベクトル化されたアプローチを望んでいました – user248237dfsf

+0

これはイテレータでインプレースで行われているのですか?いいえ、もっと効率的なやり方はありますか? AFAIK、配列をループしなければならないのは、イテレータを返すフィルター関数がないからです。 – marcog

+0

フィルターコードがNxM配列では機能しないと思います.1xMベクトルの場合のみうまくいくようです。 – user248237dfsf

1

多分あなたはインデックスあなたの行列と使用することができます。これを行う最も簡単な方法は、使用することです

import numpy as np; 
matrix = np.array([[1.,2.,3.,np.Inf],[4.,5.,6.,np.Inf],[7.,8.,9.,np.Inf]]); 
print matrix[:,1]; 
print sum(filter(lambda x: x != np.Inf,matrix[:,1])); 
print matrix[1,:]; 
print sum(filter(lambda x: x != np.Inf,matrix[1,:])); 
15

numpy.ma.masked_invalid()

a = numpy.log(numpy.arange(15)) 
a.sum() 
# -inf 
numpy.ma.masked_invalid(a).sum() 
# 25.19122118273868 
関連する問題