我写了以下脚本:
import numpy
d = numpy.array([[1089, 1093]])
e = numpy.array([[1000, 4443]])
answer = numpy.exp(-3 * d)
answer1 = numpy.exp(-3 * e)
res = answer.sum()/answer1.sum()
但我得到了这个结果,并与错误发生:
nan
C:\Users\Desktop\test.py:16: RuntimeWarning: invalid value encountered in double_scalars
res = answer.sum()/answer1.sum()
似乎是因为输入元素太小,python把它们变成了零,但是除法确实有它的结果。
如何解决这类问题?
3条答案
按热度按时间vyu0f0g11#
你不能解决它。简单地
answer1.sum()==0
,你不能执行除以零。这是因为
answer1
是2个非常大的负数的指数,因此结果被舍入为零。nan
在这种情况下返回,因为除以零。要解决这个问题,你可以:
scipy/numpy
函数,它能完全满足你的需求!查看@Warren Weckesser的答案。在这里,我解释了如何做一些数学操作,有助于这个问题。我们有这样的分子:
其中
x=3* 1089
和y=3* 1093
以上。现在,这个指数的参数是-x + log(1+exp(-y+x)) = -x + 6.1441934777474324e-06
对于分母,您可以进行类似的处理,但获得
log(1+exp(-z+k))
已经四舍五入到0
,因此分母处的指数函数的参数简单地四舍五入到-z=-3000
。这已经非常接近于如果你只保留2个前导项(即分子中的第一个数字
1089
和分母中的第一个数字1000
)的结果:为了它的缘故,让我们看看我们有多接近Wolfram alpha(link)的解决方案:
这个数字和上面的指数之间的差是
+1.7053025658242404e-13
,所以我们在分母上做的近似是好的。最后的结果是
从Wolfram alpha是(link)
同样,在这里使用numpy也是安全的。
44u64gxh2#
你可以使用
np.logaddexp
(它实现了@gg349的答案中的想法):也可以使用
scipy.special.logsumexp
:plicqrtu3#
如果将零长度(在某个维度上)数组传递给使用除法来导出其输出的numpy方法(例如
np.mean()
,np.median()
,np.var
,np.cov
等),也会出现此警告。获取此类数组的常见方法是使用某些条件过滤数组,该条件返回零长度数组。因此,如果即使您不使用非常小或非常大的数字也会引发此警告,请检查数组的形状。
举个例子: