Why does numpy.r_ sometimes include endpoints when constructing arrays, and sometimes not?

Question:

numpy.r_ can be use to build arrays quickly from slice notation. However, the following example appears to demonstrate inconsistent behavior:

>>> import numpy as np

>>> a = np.r_[0.1 : 0.3 : 0.1]
>>> a
array([0.1, 0.2])

Endpoint of the slice 0.3 not included – as expected.

>>> b = np.r_[0.1 : 0.4 : 0.1]
>>> b
array([0.1, 0.2, 0.3, 0.4])

Endpoint of the slice 0.4 included!

There does not appear to be an explanation for this behavior in the documentation.

Asked By: apsis73

||

Answers:

When c is real, numpy.r_[a:b:c] is equivalent to numpy.arange(a, b, c). Using floats here is a bad idea, as documented in the numpy.arange docs – the length may be wrong, because a length calculation based on floating-point values is subject to floating-point rounding error, and the step itself may suffer precision loss due to implementation details of how NumPy handles the step internally.

As suggested in the numpy.arange docs, you should use numpy.linspace instead. numpy.linspace takes an element count as an integer, instead of taking a step:

b = numpy.linspace(0.1, 0.4, num=3, endpoint=False)
Answered By: user2357112

because in python real numbers are not always rounded, as in your example horizontal step 0.2+0.1 is close to 0.300000000000004 and the result will be wrong.
I would use this way but it seems to be more complicated:

from decimal import *
import numpy as np
getcontext().prec = 6 # setting new values for precision, rounding, or enabled traps
b = Decimal(2)/Decimal(5) # 0.4
a = Decimal(1)/Decimal(10) # 0.1
print(np.r_[a: b : a])
Answered By: Zz_GhostM4n_zZ
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.