Numpy, divide by zero: two different results for the same operation
在搜索了一点之后,我仍然在和numpy中零的除法作斗争。我对我马上报告的矛盾感到震惊:
1 2 3 4 5 6
| 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失败的尝试。
- 在第一种情况下,你是在处理整数,而在第二种情况下,你是在处理一个numpy数组吗?这些都是不同的事情,行为也会有所不同,这取决于如何为每个操作定义操作。我认为,如果您想要一致的输出,您必须为函数提供一致的输入类型,或者至少为在操作下行为相同的类型。
1.是一个普通的python float,它们会引发异常,而不是使用nan/inf。当您调用f(1.)时,numpy不会以任何方式参与其中。仅仅执行from numpy import *(或者调用像seterr这样的numpy函数)并不能改变普通python类型的工作方式;它只会影响numpy对象的操作,并且只有显式创建numpy对象时,才会获得numpy对象。
当您显式地创建一个numpy对象时,例如在您的f(z)示例中,您将涉及numpy,它有自己的类型,不同于基本的python类型。值得注意的是,numpy数字类型确实使用了nan/inf。
据我所知,没有办法让普通的python float开始返回nan或inf,而不是引发异常,因此如果您希望同时支持标量和向量操作,那么必须使用numpy scalars而不是plain python float(如本问题所述)。
- np.divide(1.0,0.0)inf与报酬的警告。它可能会从numpy进出divide不知何故?这使义不在第一位?
- andrasdeak":你得到的警告,因为你仍然在穿越平原的Python浮点数。例如,如果你的np.divide(np.float64(1.0), 0),你不会得到警告。如果你想对发生的一切你需要在你的numpy,对象的类型是numpy你开始之前做numpy在线他们数学。(或者你可以只是Live With The警告。)
- "你可以和andrasdeak:是的,从numpy divide进出,但那不会改变如何/Python浮点算符平原上工作。我将要1.0/0.0numpy CAN的工作differently平原。
- 谢谢你的澄清。
numpy与你的函数f无关。如果你想改变输出,你必须抓住ZeroDivisionError。
1 2 3 4 5 6 7
| import numpy
def f(x) :
try:
return 1./(x-1.)
except ZeroDivisionError:
return numpy.nan |
或者使用Numpy的划分:
1 2 3 4
| import numpy
def f(x) :
return numpy.divide(1., (x-1.)) |
或者只将numpy类型传递给f:
1 2 3 4 5 6 7
| import numpy
def f(x) :
return 1./(x-1.)
x = numpy.float_(1)
print f(x) # prints inf |
- 它的伟大工程,谢谢。想象一下,有很多的功能,但我想在我和我的每一个函数的脚本不需要这样的行为对你的代码suggest appending)到每个他们。你知道,如果这是可能的吗?
- 是的,它是!但如果你使用的是numpy.divide()。这将给你的inf违约。更新我的答案。
- 我发现你最后的建议尤其是有用的,因为与它,我没有任何的变化,在我的f(x)(原函数在脚本处理我,我有很多复杂的功能,和我一样的变化,将不numpy.divide湿地旁)。I意味着fcan redefined f(numpy.float_(x))是容易计算,这是和做的工作。感谢很多为您的编辑。
它看起来像seterr用于numpy类型;它如何与python本机类型一起使用。另一方面,如果你这样做:
您的seterr不应出现错误。