问题
After having searched around a little bit, I'm still struggling with divisions by zero in numpy. I am stunned by the contradiction I report right away:
from numpy import *
seterr(all='ignore') # Trying to avoid ZeroDivisionError, but unsuccessful.
def f(x) :
return 1./(x-1.)
With this, when I execute f(1.)
, I get
ZeroDivisionError: float division by zero
.
However, when I define
z = array( [ 1., 1. ] )
and execute f(z)
, I do not get any error, but
array([ inf, inf])
.
As you can see, there is kind of a contradiction between both outputs. My first question is why.
Ideally, I would like to get inf
as the output of f(1.)
, or at least nan
, but not an error (and therefore the stoppage of the calculation).
My second question is how to manage this.
Notice my failed attempt by making use of seterr
.
回答1:
Numpy is not involved in your function f
. You'll have to catch the ZeroDivisionError
if you want to alter the output.
import numpy
def f(x) :
try:
return 1./(x-1.)
except ZeroDivisionError:
return numpy.nan
Or use numpy's division:
import numpy
def f(x) :
return numpy.divide(1., (x-1.))
Or only pass numpy types to f
:
import numpy
def f(x) :
return 1./(x-1.)
x = numpy.float_(1)
print f(x) # prints inf
回答2:
1.
is an ordinary Python float, and these raise exceptions instead of using nan/inf. When you call f(1.)
, numpy is not involved in any way. Just doing from numpy import *
(or calling numpy functions like seterr
) doesn't change anything about how ordinary Python types work; it will only affect operations on numpy objects, and you only get numpy objects if you explicitly create them.
When you do explicitly create a numpy object, as in your f(z)
example, you involve numpy, which has its own types that differ from the basic Python types. Notably, numpy numeric types do use nan/inf.
As far as I know, there is no way to get plain Python floats to start returning nan
or inf
instead of raising exceptions, so you'll have to use numpy scalars instead of plain Python floats (as described in this question) if you want to support both scalar and vector operations.
回答3:
It looks like seterr
is intended to be used with Numpy types; how could it be used with Python native type. On the other hand, if you do:
f(np.array((1,)))
No error should occur with your seterr
.
来源:https://stackoverflow.com/questions/34664250/numpy-divide-by-zero-two-different-results-for-the-same-operation