Search code examples
pythonpython-3.xnumpyrandomuniform-distribution

In Python with numpy, how to get uniformely distributed random floats between 0 and a natural x, including both?


In Python with numpy, for a given natural number x, we'd like to get an array (say, 20×2 or whichever shape you wish) of uniformly distributed floats in the interval [0,x]. Notice that the interval is closed.

Based on http://stackoverflow.com/a/33359758, a completely screwed approach is

x=10
print(np.reshape([int.from_bytes(os.urandom(8))*x/((1<<64)-1) for i in range(40)],(20,2)))

However, the results depend on the operating system. I also don't see whether/why the obtained numbers could be uniformly distributed.

Notice that a (different) approach of somehow obtaining uniform IEEE 754 floats from [0,1] and then multiplying them by x is potentially flawed because, unless x is a power of 2, your numerators (in terms of the representation as numerator * 2^{…}) will always be multiples of x, whereas all non-multiples of x would never show up.

Any help? Pseudo-random numbers would also do (assuming that they are uniformly distributed).

You can also assume that x is small, say, x<2^8, if it helps.


Solution

  • You could adjust the endpoint to the next floating point number after the max:

    import numpy as np
    
    def uniform_with_endpoint(low=0, hi=1, size=None):
      return np.random.uniform(low, np.nextafter(hi, np.inf), size=size)
    

    This gives a uniform distribution in which hi is included in the possible results.