Python 防止Numpy生成NAN
我有一个数字代码,数字可以任意变小。我目前正在使用Python 防止Numpy生成NAN,python,numpy,Python,Numpy,我有一个数字代码,数字可以任意变小。我目前正在使用numpy.nan\u to_num生成小值0。有没有办法阻止numpy首先使用NaN 例如,考虑这种情况: import numpy a = numpy.array([0]) / numpy.array([0.]) 给出数组([nan])。如果我随后执行numpy.nan\u to_num(a),我会得到array([0.])。有没有办法绕过手动nan\u to_num步骤,让numpy不使用nans 我想指出,在我的代码中,我没有将0除以
numpy.nan\u to_num
生成小值0
。有没有办法阻止numpy首先使用NaN
例如,考虑这种情况:
import numpy
a = numpy.array([0]) / numpy.array([0.])
给出数组([nan])
。如果我随后执行numpy.nan\u to_num(a)
,我会得到array([0.])
。有没有办法绕过手动nan\u to_num
步骤,让numpy
不使用nan
s
我想指出,在我的代码中,我没有将0除以0。有一些步骤可以生成NAN(比如一个根为0的根查找应用程序),但如果不提供大量代码,我无法创建一个MCVE来复制NAN。
这很重要,因为我想防止奇怪的下溢问题假设我们有下面非常简单的Numpy示例
In [0]: import numpy as np
...:
...: x_in = np.arange(1000, 1003, 1.0)
...:
...: def f(x):
...: return np.exp(2*x+1)/np.exp(3*x-2)
...: f(x_in)
Out[0]: array([ nan, nan, nan])
其中,函数f
执行一些计算并返回输入向量x_的NaNs
处理这个问题可能有多种方法
默认情况下,numpy使用64位浮点数。在这种特殊情况下,只需将输入向量转换为128位即可解决问题
In [1]: f(x_in.astype('float128'))
Out[1]: array([ 1.0195336e-433, 3.7506545e-434, 1.3797887e-434], dtype=float128)
以一些额外的计算成本为代价
正确的方法将是考虑为什么出现,并改写函数以避免64位浮点,
In [2]: def f(x):
...: # using the fact that exp(a)/exp(b) = exp(a-b)
...: return np.exp((2*x-1) - (3*x-2))
...: f(x_in)
...:
Out[2]: array([ 0., 0., 0.])
最后,在极少数情况下,当我们不能(或不想)重写数学问题时,我们可以使用任意精度的浮点
结果可以转换为具有res.astype('float64')
的常规numpy数组。不过,对于大型阵列而言,这将非常缓慢
在任何情况下,您都需要知道代码的哪一部分生成了NAN,以便对此做些什么
顺便说一句,使用numpy.nan\u to_num
将nan替换为0.0
从根本上讲是错误的,除非您知道这些nan发生的确切原因。因为NaN可以是任何数字,而不必是0。例如,
np.exp(-1000+1)/np.exp(-1000-1)
将导致带有64位浮点的NaN,而正确答案是np.exp(2)
=7.389
我想你不明白为什么0/0是NaN。这不是底流状态。你应该先问问自己为什么要除以零。防止Numpy生成NaN的一种方法是在执行可以生成NaN的操作之前编写正确的代码并检查输入。@Paul,David,请参阅更新。我仍然认为你没有完全理解这一点。你似乎有意掩盖这件事。你不会告诉我们你是如何得到这些NAN的,这表明你认为这并不重要。根据我的经验,这种情况不太可能发生。拥抱南部并找到适当的方法来处理它们;例如,使用由NAN定义的屏蔽数组。
In [3]: import mpmath as mp
...:
...: def f(x):
...: mpexp_vect = np.frompyfunc(mp.exp, 1, 1)
...: res = mpexp_vect(2*x+1)/mpexp_vect(3*x-2)
...: return res
...: f(x_in)
...:
Out[3]: array([mpf('1.0195335985731257e-433'), mpf('3.7506545049859113e-434'),
mpf('1.3797886833213697e-434')], dtype=object)