Numpy,除以零:同一操作的两个不同结果

Numpy, divide by zero: two different results for the same operation

经过一番搜索后,我仍在努力解决 numpy 中被零除的问题。 我被我马上报告的矛盾惊呆了:

from numpy import *

seterr(all='ignore')    # Trying to avoid ZeroDivisionError, but unsuccessful.

def f(x) :
    return 1./(x-1.)

有了这个,当我执行 f(1.) 时,我得到 ZeroDivisionError: float division by zero.

然而,当我定义 z = array( [ 1., 1. ] ) 并执行 f(z),我没有收到任何错误,但是 array([ inf, inf]).

如您所见,两个输出之间存在某种矛盾。 我的第一个问题是为什么。

理想情况下,我希望得到 inf 作为 f(1.) 的输出,或者至少 nan,但不是错误(因此停止计算)。 我的第二个问题 是如何管理它。 通过使用 seterr.

注意我失败的尝试

1. 是一个普通的 Python 浮点数,它们引发异常而不是使用 nan/inf。当您调用 f(1.) 时,numpy 不会以任何方式参与。只是做 from numpy import *(或调用像 seterr 这样的 numpy 函数)不会改变普通 Python 类型的工作方式;它只会影响对 numpy 对象的操作,并且只有明确创建它们才能获得 numpy 对象。

当你显式创建一个numpy对象时,就像在你的f(z)示例中一样,你涉及到numpy,它有自己的类型,不同于基本的Python 类型。值得注意的是,numpy 数字类型 do 使用 nan/inf.

据我所知,没有办法让普通的 Python 浮点数开始返回 naninf 而不是引发异常,所以你必须使用如果您想同时支持标量和向量运算,则使用 numpy 标量而不是普通 Python 浮点数(如 this question 中所述)。

看起来 seterr 旨在与 Numpy 类型一起使用;它如何与 Python 本机类型一起使用。另一方面,如果您这样做:

f(np.array((1,)))

您的 seterr.

应该不会出现错误

Numpy 未参与您的函数f。如果你想改变输出,你必须抓住 ZeroDivisionError

import numpy

def f(x) :
    try:
        return 1./(x-1.)
    except ZeroDivisionError:
        return numpy.nan

或者使用numpy的除法:

import numpy

def f(x) :
    return numpy.divide(1., (x-1.))

或仅将 numpy 类型传递给 f:

import numpy

def f(x) :
    return 1./(x-1.)

x = numpy.float_(1)
print f(x) # prints inf