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.
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.
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.
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.
In Python, division by zero generates the exception ZeroDivisionError: division by zero. This is because in mathematics, division by zero is undefined.
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
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With