浮動小数点数の大きなデータセットがあります。それらを繰り返し処理し、それぞれについてnp.log(x)
を評価します。私は得る
RuntimeWarning: divide by zero encountered in log
これを回避し、このエラーが発生した場合は0を返します。
私は新しい関数を定義することを考えています:
def safe_ln(x):
#returns: ln(x) but replaces -inf with 0
l = np.log(x)
#if l = -inf:
l = 0
return l
基本的に、出力が-inf
であることをテストする方法が必要ですが、処理方法がわかりません。ご協力ありがとうございました!
x=0
のlog
はマイナスの無限大なので、入力値がゼロであるかどうかを確認し、必要なものを返します。
def safe_ln(x):
if x <= 0:
return 0
return math.log(x)
[〜#〜] edit [〜#〜]:小さな編集:0以下のすべての値をチェックする必要があります。
EDIT 2:np.log
は、numpy配列で計算する関数です。単一の値の場合は、math.log
を使用する必要があります。これは、numpyで上記の関数がどのように見えるかです:
def safe_ln(x, minval=0.0000000001):
return np.log(x.clip(min=minval))
あなたはnp関数を使用しているので、numpy配列で作業していると安全に推測できますか?これを行う最も効率的な方法は、forループの代わりにwhere関数を使用することです
myarray= np.random.randint(10,size=10)
result = np.where(myarray>0, np.log(myarray), 0)
それ以外の場合は、単にログ関数を使用してから、ホールにパッチを適用できます。
myarray= np.random.randint(10,size=10)
result = np.log(myarray)
result[result==-np.inf]=0
Np.log関数は、値0で使用すると-infを正しく返します。したがって、0を返しますか?どこかで元の値に戻す必要がある場合は、ゼロを1に変更する問題が発生します...
あなたはこれを行うことができます。
def safe_ln(x):
try:
l = np.log(x)
except ZeroDivisionError:
l = 0
return l
例外処理を使用します。
In [27]: def safe_ln(x):
try:
return math.log(x)
except ValueError: # np.log(x) might raise some other error though
return float("-inf")
....:
In [28]: safe_ln(0)
Out[28]: -inf
In [29]: safe_ln(1)
Out[29]: 0.0
In [30]: safe_ln(-100)
Out[30]: -inf
Enricoの答えは素晴らしいですが、どちらのソリューションでも警告が出ます:
RuntimeWarning: divide by zero encountered in log
別の方法として、where
関数を引き続き使用できますが、適切な場合にのみメインの計算を実行します。
# alternative implementation -- a bit more typing but avoids warnings.
loc = np.where(myarray>0)
result2 = np.zeros_like(myarray, dtype=float)
result2[loc] =np.log(myarray[loc])
# answer from Enrico...
myarray= np.random.randint(10,size=10)
result = np.where(myarray>0, np.log(myarray), 0)
# check it is giving right solution:
print(np.allclose(result, result2))
私のユースケースは除算用でしたが、原則は明らかに同じです:
x = np.random.randint(10, size=10)
divisor = np.ones(10,)
divisor[3] = 0 # make one divisor invalid
y = np.zeros_like(divisor, dtype=float)
loc = np.where(divisor>0) # (or !=0 if your data could have -ve values)
y[loc] = x[loc] / divisor[loc]
あなたができる:
def safe_ln(x):
#returns: ln(x) but replaces -inf with 0
try:
l = np.log(x)
except RunTimeWarning:
l = 0
return l