Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RuntimeWarning: Divide by Zero error: How to avoid? PYTHON, NUMPY

Tags:

python

numpy

I am running in to RuntimeWarning: Invalid value encountered in divide

 import numpy
 a = numpy.random.rand((1000000, 100))
 b = numpy.random.rand((1,100))
 dots = numpy.dot(b,a.T)/numpy.dot(b,b)
 norms = numpy.linalg.norm(a, axis =1)
 angles = dots/norms ### Basically I am calculating angle between 2 vectors 

There are some vectors in my a which have norm as 0. so while calculating angles it is giving runtime warning.

Is there a one line pythonic way to compute angles while taking into account norms which are 0?

angles =[i/j if j!=0 else -2 for i,j in zip(dots, norms)] # takes 10.6 seconds

But it takes a lot of time. Since all angles will have values between 1 and -1 and I need only 10 max values this will help me. This takes around 10.6 seconds which is insane.

like image 377
pg2455 Avatar asked Aug 01 '14 19:08

pg2455


People also ask

How do I avoid division by zero in Numpy?

Behavior on division by zero can be changed using seterr. When both x1 and x2 are of an integer type, divide will return integers and throw away the fractional part. Moreover, division by zero always yields zero in integer arithmetic. >>> np.

How do you ignore division by zero in Python?

You can't divide by zero! If you don't specify an exception type on the except line, it will cheerfully catch all exceptions. This is generally a bad idea in production code, since it means your program will blissfully ignore unexpected errors as well as ones which the except block is actually prepared to handle.

How can you prevent Runtimewarning divide by zero encountered in log?

I solved this by finding the lowest non-zero number in the array and replacing all zeroes by a number lower than the lowest :p. Note that all numbers get a tiny fraction added to them. Save this answer.

What happens when you divide by zero in Python?

In Python, division by zero generates the exception ZeroDivisionError: division by zero. This is because in mathematics, division by zero is undefined.


2 Answers

you can ignore warings with the np.errstate context manager and later replace nans with what you want:

import numpy as np
angle = np.arange(-5., 5.) 
norm = np.arange(10.)
with np.errstate(divide='ignore'):
    print np.where(norm != 0., angle / norm, -2)
# or:
with np.errstate(divide='ignore'):
    res = angle/norm
res[np.isnan(res)] = -2
like image 177
jtaylor Avatar answered Oct 06 '22 22:10

jtaylor


In newer versions of numpy there is a third alternative option that avoids needing to use the errstate context manager.

All Numpy ufuncs accept an optional "where" argument. This acts slightly differently than the np.where function, in that it only evaluates the function "where" the mask is true. When the mask is False, it doesn't change the value, so using the "out" argument allows us to preallocate any default we want.

import numpy as np

angle = np.arange(-5., 5.)
norm = np.arange(10.)

# version 1
with np.errstate(divide='ignore'):
    res1 = np.where(norm != 0., angle / norm, -2)

# version 2
with np.errstate(divide='ignore'):
    res2 = angle/norm
res2[np.isinf(res2)] = -2

# version 3
res3 = -2. * np.ones(angle.shape)
np.divide(angle, norm, out=res3, where=norm != 0)

print(res1)
print(res2)
print(res3)

np.testing.assert_array_almost_equal(res1, res2)
np.testing.assert_array_almost_equal(res1, res3)
like image 5
DStauffman Avatar answered Oct 06 '22 21:10

DStauffman