我遇到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.])
Run Code Online (Sandbox Code Playgroud)
但是,在一段代码的深处,我减去了两个np.float64 ndarray对象,并得到一个浮点异常。导致异常的数组包含一些非常大和很小的数字(例如1e307和1e-307)和一些nans,但是我没有对这些数字进行任何组合来单独进行异常测试。
更令人不安的是,我有大量的Jenkins测试网格,它们使用numpy,matplotlib,python和scipy的许多版本运行完全相同的代码,但没有一个引发此异常。我现在迷路了-我不知道是否存在错误,或者是否存在错误,如何进行跟踪。
如果您对病态好奇,可以考虑使用的代码为pyspeckit,并且测试在第20行失败test_hr2421.py。
编辑:后续操作-我认为这np.seterr(invalid='raise')是一个小片段:在我正在导入的模块中,特别是在pymc中被调用,并且pull请求自此阻止了此更改。
Numpy 对于如何处理浮点错误具有可配置的行为。默认情况下,下溢错误会被忽略,而其他错误则会触发警告。对于每个类别,用户可以使用 更改此行为numpy.seterr。这些设置是全局的 \xe2\x80\x94 这里没有命名空间;因此,如果一个库调用numpy.seterr(all=\'raise\'),那么这将影响整个程序,直到numpy.seterr再次调用。
您可以确认这确实是您问题的原因
\nprint(numpy.seterr())\nRun Code Online (Sandbox Code Playgroud)\n应该输出类似的内容
\n{\'divide\': \'warn\', \'over\': \'warn\', \'under\': \'ignore\', \'invalid\': \'warn\'}\nRun Code Online (Sandbox Code Playgroud)\n如果其中一些类别具有 value raise,特别是 key \'invalid\',那么这将解释您所观察到的行为。
您可以通过调用numpy.seterr(invalid=\'warn\')、 或 来抑制此异常invalid=\'ignore\'。有关可能错误的完整列表,请阅读 的文档numpy.seterr。
您还可以使用上下文管理器来临时更改行为:
\nIn [12]: x = np.arange(-5, 5,dtype=\'float64\')\n\nIn [13]: with np.errstate(divide="raise"):\n print(1/x)\n ....: \n---------------------------------------------------------------------------\nFloatingPointError Traceback (most recent call last)\n<ipython-input-13-881589fdcb7a> in <module>()\n 1 with np.errstate(divide="raise"):\n----> 2 print(1/x)\n 3 \n\nFloatingPointError: divide by zero encountered in true_divide\n\nIn [14]: with np.errstate(divide="warn"):\n print(1/x)\n ....: \n/home/users/gholl/venv/stable-3.5/bin/ipython3:2: RuntimeWarning: divide by zero encountered in true_divide\n \n[-0.2 -0.25 -0.33333333 -0.5 -1. inf\n 1. 0.5 0.33333333 0.25 ]\n\nIn [15]: with np.errstate(divide="ignore"):\n print(1/x)\n ....: \n[-0.2 -0.25 -0.33333333 -0.5 -1. inf\n 1. 0.5 0.33333333 0.25 ]\nRun Code Online (Sandbox Code Playgroud)\n我倾向于将整个代码包装在一个with np.errstate(all="raise")块中,然后使用上下文管理器忽略特定条件,如果我确定问题不是隐藏错误 \xe2\x80\x94 ,但它通常是这样。
如果确实有一个库永久地改变了状态,我会向维护者提出问题或发送拉取请求,因为他们确实应该使用上下文管理器,这样他们的更改设置仅适用于他们的代码块,而不适用于程序的其余部分。
\n| 归档时间: |
|
| 查看次数: |
11390 次 |
| 最近记录: |