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)