我有一个浮点数大的数据集。我遍历它们并为每个评估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
的方法,但我不知道如何继续。
谢谢你的帮助!
答案 0 :(得分:32)
您正在使用np函数,所以我可以安全地猜测您正在使用numpy数组? 那么最有效的方法是使用where函数而不是for循环
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 :(得分:22)
由于log
的{{1}}为负无限,我只需检查输入值是否为零并返回您想要的任何内容:
x=0
编辑:小编辑:您应检查所有小于或等于0的值。
编辑2 :def safe_ln(x):
if x <= 0:
return 0
return math.log(x)
当然是在numpy数组上计算的函数,对于单个值,您应该使用np.log
。这就是上面的函数看起来如何使用numpy:
math.log
答案 2 :(得分:3)
你可以这样做。
def safe_ln(x):
try:
l = np.log(x)
except ZeroDivisionError:
l = 0
return l
答案 3 :(得分:1)
使用异常处理:
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
答案 4 :(得分:0)
def safe_ln(x):
#returns: ln(x) but replaces -inf with 0
try:
l = np.log(x)
except RunTimeWarning:
l = 0
return l
答案 5 :(得分:0)
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]
答案 6 :(得分:0)
我喜欢如下使用sys.float_info.min
:
>>> import numpy as np
>>> import sys
>>> arr = np.linspace(0.0, 1.0, 3)
>>> print(arr)
[0. 0.5 1. ]
>>> arr[arr < sys.float_info.min] = sys.float_info.min
>>> print(arr)
[2.22507386e-308 5.00000000e-001 1.00000000e+000]
>>> np.log10(arr)
array([-3.07652656e+02, -3.01029996e-01, 0.00000000e+00])
其他答案也引入了引入的较小的正值,但是当我估算的结果太小而无法处理时,我更喜欢使用最小的有效输入。