171

I haven't been able to find a function to generate an array of random floats of a given length between a certain range.

I've looked at Random sampling but no function seems to do what I need.

random.uniform comes close but it only returns a single element, not a specific number.

This is what I'm after:

ran_floats = some_function(low=0.5, high=13.3, size=50)

which would return an array of 50 random non-unique floats (ie: repetitions are allowed) uniformly distributed in the range [0.5, 13.3].

Is there such a function?

3
  • 5
    You've tagged the question numpy, but you didn't mention numpy.random.uniform, even though it has exactly the call signature you want. Do you have the numpy library available? Commented Feb 27, 2014 at 14:56
  • 2
    [random.uniform(low, high) for i in xrange(size)] Commented Feb 27, 2014 at 14:56
  • 1
    @DSM yes I have and you are apparently 100% correct. I missed that function and it appears to do exactly what I need. Would you mind presenting your comment as an answer? Commented Feb 27, 2014 at 14:59

10 Answers 10

264

np.random.uniform fits your use case:

sampl = np.random.uniform(low=0.5, high=13.3, size=(50,))

Update Oct 2019:

While the syntax is still supported, it looks like the API changed with NumPy 1.17 to support greater control over the random number generator. Going forward the API has changed and you should look at https://docs.scipy.org/doc/numpy/reference/random/generated/numpy.random.Generator.uniform.html

The enhancement proposal is here: https://numpy.org/neps/nep-0019-rng-policy.html

Sign up to request clarification or add additional context in comments.

4 Comments

OP's intuitive search question is some_function(low=0.5, high=13.3, size=50). That's how well python libs are designed #wow
Size was not completely clear and link does not work. Here is a minor clarification. size: int or tuple of ints, optional. Output shape. If the given shape is, e.g., (m, n, k), then m * n * k samples are drawn. If size is None default), a single value is returned if low and high are both scalars.
@vlad - thanks for pointing out the issue with the link. I've updated the answer to hopefully cover the current usage.
In the official documentation of Numpy, the following function resolves the problem. numpy.org/doc/stable/reference/random/generated/…
32

Why not use a list comprehension?

In Python 2

ran_floats = [random.uniform(low,high) for _ in xrange(size)]

In Python 3, range works like xrange(ref)

ran_floats = [random.uniform(low,high) for _ in range(size)]

1 Comment

Thanks for sharing a solution using built-in python modules.
11

This is the simplest way

np.random.uniform(start,stop,(rows,columns))

Comments

8

There may already be a function to do what you're looking for, but I don't know about it (yet?). In the meantime, I would suggess using:

ran_floats = numpy.random.rand(50) * (13.3-0.5) + 0.5

This will produce an array of shape (50,) with a uniform distribution between 0.5 and 13.3.

You could also define a function:

def random_uniform_range(shape=[1,],low=0,high=1):
    """
    Random uniform range

    Produces a random uniform distribution of specified shape, with arbitrary max and
    min values. Default shape is [1], and default range is [0,1].
    """
    return numpy.random.rand(shape) * (high - min) + min

EDIT: Hmm, yeah, so I missed it, there is numpy.random.uniform() with the same exact call you want! Try import numpy; help(numpy.random.uniform) for more information.

Comments

7

Alternatively you could use SciPy

from scipy import stats
stats.uniform(0.5, 13.3).rvs(50)

and for the record to sample integers it's

stats.randint(10, 20).rvs(50)

Comments

5

Why not to combine random.uniform with a list comprehension?

>>> def random_floats(low, high, size):
...    return [random.uniform(low, high) for _ in xrange(size)]
... 
>>> random_floats(0.5, 2.8, 5)
[2.366910411506704, 1.878800401620107, 1.0145196974227986, 2.332600336488709, 1.945869474662082]

Comments

4

The for loop in list comprehension takes time and makes it slow. It is better to use numpy parameters (low, high, size, ..etc)

import numpy as np
import time
rang = 10000
tic = time.time()
for i in range(rang):
    sampl = np.random.uniform(low=0, high=2, size=(182))
print("it took: ", time.time() - tic)

tic = time.time()
for i in range(rang):
    ran_floats = [np.random.uniform(0,2) for _ in range(182)]
print("it took: ", time.time() - tic)

sample output:

('it took: ', 0.06406784057617188)

('it took: ', 1.7253198623657227)

Comments

2

Alternatively, if you are OK with a list of real numbers instead, you can use the standard random.randrange:

def some_function(low, high, size):
    low_int = int(low * 1000)
    high_int = int(high *1000)
    return [random.randrange(low_int, high_int, size)/1000 for _ in range(size)]

Comments

0

np.random.random_sample(size) will generate random floats in the half-open interval [0.0, 1.0).

Comments

0

This should work for your example

sample = (np.random.random([50, ]) * 13.3) - 0.5

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.