python numpy arange unexpected results
Solution 1:
I'm guessing that you're seeing the effects of floating point rounding.
numpy.arange
does the same thing as python's range
: It doesn't include the "endpoint". (e.g. range(0, 4, 2)
will yield [0,2]
instead of [0,2,4]
)
However, for floating point steps, the rounding errors are accumulate, and occasionally the last value will actually include the endpoint.
As noted in the documentation for arange
:
When using a non-integer step, such as 0.1, the results will often not be consistent. It is better to use
linspace
for these cases.
numpy.linspace
generates a specified number of points between a starting and ending point. Incidentally, it does include the endpoints by default.
Solution 2:
Perhaps it has to do with limitations on floating point numbers. Due to machine precision, it is not possible to store every conceivable value perfectly as a floating point. For example:
>>> 8.4
8.4000000000000004
>>> 8.35
8.3499999999999996
So, 8.4 as a floating point is slightly greater than the actual value of 8.4, while 8.35 as a floating point is a tiny bit less.
Solution 3:
the help of arange function says
For floating point arguments, the length of the result is
``ceil((stop - start)/step)``. Because of floating point overflow,
this rule may result in the last element of `out` being greater
than `stop`.
for python 2.7, Conversions between floating-point numbers and strings are now correctly rounded on most platforms.
in 2.7
>>> float(repr(2.3))
2.3
in 2.6
>>> float(repr(2.3))
2.2999999999999998
Solution 4:
I had the same problem and I implemented my own function to correct for this rounding issue with numpy.arange :
import numpy as np
def my_arange(a, b, dr, decimals=6):
res = [a]
k = 1
while res[-1] < b:
tmp = round(a + k*dr,decimals)
if tmp > b:
break
res.append(tmp)
k+=1
return np.asarray(res)