带有RuntimeWarning的numpy除法:在double_scalars中遇到无效的值 [英] numpy division with RuntimeWarning: invalid value encountered in double_scalars

查看:167
本文介绍了带有RuntimeWarning的numpy除法:在double_scalars中遇到无效的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了以下脚本:

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()
print res

但是我得到了这个结果,并且发生了错误:

But I got this result and with the error occurred:

nan
C:\Users\Desktop\test.py:16: RuntimeWarning: invalid value encountered in double_scalars
  res = answer.sum()/answer1.sum()

输入元素似乎太小,以至于python将它们设为零,但是除法的确有其结果.

It seems to be that the input element were too small that python turned them to be zeros, but indeed the division has its result.

如何解决此类问题?

推荐答案

您无法解决.只需answer1.sum()==0,就不能执行零除.

You can't solve it. Simply answer1.sum()==0, and you can't perform a division by zero.

之所以会发生这种情况,是因为answer1是2个非常大的负数的指数,因此结果四舍五入为零.

This happens because answer1 is the exponential of 2 very large, negative numbers, so that the result is rounded to zero.

nan.

现在要解决您的问题,您可以:

Now to solve your problem you could:

  • 使用高精度数学库,例如 mpmath .但这没那么有趣.
  • 作为较大武器的替代方法,请进行一些数学操作,如下所述.
  • 使用量身定制的scipy/numpy函数,该函数可以完全满足您的需求!查看@Warren Weckesser的答案.
  • go for a library for high-precision mathematics, like mpmath. But that's less fun.
  • as an alternative to a bigger weapon, do some math manipulation, as detailed below.
  • go for a tailored scipy/numpy function that does exactly what you want! Check out @Warren Weckesser answer.

在这里,我解释了如何进行一些数学运算以帮助解决此问题.我们将其用于分子:

Here I explain how to do some math manipulation that helps on this problem. We have that for the numerator:

exp(-x)+exp(-y) = exp(log(exp(-x)+exp(-y)))
                = exp(log(exp(-x)*[1+exp(-y+x)]))
                = exp(log(exp(-x) + log(1+exp(-y+x)))
                = exp(-x + log(1+exp(-y+x)))

x=3* 1089y=3* 1093的上方.现在,这个指数的参数是

where above x=3* 1089 and y=3* 1093. Now, the argument of this exponential is

-x + log(1+exp(-y+x)) = -x + 6.1441934777474324e-06

对于分母,您可以类似地进行操作,但获得的结果是log(1+exp(-z+k))已四舍五入为0,因此分母处的指数函数的参数仅四舍五入为-z=-3000.然后,您得到的结果是

For the denominator you could proceed similarly but obtain that log(1+exp(-z+k)) is already rounded to 0, so that the argument of the exponential function at the denominator is simply rounded to -z=-3000. You then have that your result is

exp(-x + log(1+exp(-y+x)))/exp(-z) = exp(-x+z+log(1+exp(-y+x)) 
                                   = exp(-266.99999385580668)

已经非常接近您仅保留两个前导项(即分子中的第一个数字1089和分母中的第一个数字1000)所得到的结果:

which is already extremely close to the result that you would get if you were to keep only the 2 leading terms (i.e. the first number 1089 in the numerator and the first number 1000 at the denominator):

exp(3*(1089-1000))=exp(-267)

为此,让我们看看距Wolfram alpha解决方案有多远(

For the sake of it, let's see how close we are from the solution of Wolfram alpha (link):

Log[(exp[-3*1089]+exp[-3*1093])/([exp[-3*1000]+exp[-3*4443])] -> -266.999993855806522267194565420933791813296828742310997510523

该数字与上面的指数之差为+1.7053025658242404e-13,因此我们在分母处的近似值很好.

The difference between this number and the exponent above is +1.7053025658242404e-13, so the approximation we made at the denominator was fine.

最终结果是

'exp(-266.99999385580668) = 1.1050349147204485e-116

从Wolfram alpha到(

From wolfram alpha is (link)

1.105034914720621496.. × 10^-116 # Wolfram alpha.

同样,在这里也可以使用numpy.

and again, it is safe to use numpy here too.

这篇关于带有RuntimeWarning的numpy除法:在double_scalars中遇到无效的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆