numpy FloatingPointError:减法中遇到的值无效 - 不可重现?

时间:2012-08-20 17:08:20

标签: python numpy

我在一段测试代码中遇到FloatingPointError: invalid value encountered in subtract。异常开始引发而代码本身没有任何变化,所以我很难理解它。

我的问题:导致invalid value encountered in subtract例外的原因是什么?为什么在python + numpy的不同安装上它的表现会有所不同?

详情:

这个MWE 引发FloatingPointError

>>> import numpy as np
>>> np.__version__
 '1.6.1'
>>> x = np.arange(5,dtype='float64')
>>> y = np.ones(5,dtype='float64')
>>> x[2]=np.nan
>>> x-y
# array([ -1.,   0.,  nan,   2.,   3.])

但是,在一段代码的深处,我减去了两个np.float64 ndarray个对象,并得到一个浮点异常。导致异常的数组包含一些非常庞大和微小的数字(例如,1e307和1e-307)以及一些nan s,但我还没有对这些数字进行任何组合导致我的异常测试自己的。

更令人不安的是,我有一个大网格的Jenkins测试运行与numpy,matplotlib,python和scipy的许多版本完全相同的代码,并且它们中的NONE引发了这个异常。我此时已经迷路了 - 我不知道是否有错误,或者是否有错误,如何追踪它。

如果您感到病态好奇,相关代码为pyspeckit,且test_hr2421.py第20行的测试失败。

编辑:后续行动 - 我认为这个小片段:np.seterr(invalid='raise')在我导入的模块中被调用,特别是pymc,并且拉请求已经阻止了此更改。

1 个答案:

答案 0 :(得分:2)

Numpy在如何处理错误方面具有可配置的行为。默认情况下会忽略某些错误,其他错误会导致警告。对于每个类别,您可以更改此行为。有人必须将其设置为引发错误,而不是将其更改回来。

您可以通过调用numpy.seterr(invalid='warn')invalid='ignore'来取消此异常。有关可能错误的完整列表,请阅读numpy.seterr

的文档

您还可以使用上下文管理器:

In [12]: x = np.arange(-5, 5,dtype='float64')

In [13]: with np.errstate(divide="raise"):
    print(1/x)
   ....:     
---------------------------------------------------------------------------
FloatingPointError                        Traceback (most recent call last)
<ipython-input-13-881589fdcb7a> in <module>()
      1 with np.errstate(divide="raise"):
----> 2     print(1/x)
      3 

FloatingPointError: divide by zero encountered in true_divide

In [14]: with np.errstate(divide="warn"):
    print(1/x)
   ....:     
/home/users/gholl/venv/stable-3.5/bin/ipython3:2: RuntimeWarning: divide by zero encountered in true_divide

[-0.2        -0.25       -0.33333333 -0.5        -1.                 inf
  1.          0.5         0.33333333  0.25      ]

In [15]: with np.errstate(divide="ignore"):
    print(1/x)
   ....:     
[-0.2        -0.25       -0.33333333 -0.5        -1.                 inf
  1.          0.5         0.33333333  0.25      ]

我倾向于将整个代码包装在with np.errstate(all="raise")块中,然后使用上下文管理器忽略特定条件,如果我确定问题没有隐藏错误 - 它通常是。 / p>