Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw 2D random uniform samples from two ranges

Tags:

python

numpy

I have two pairs of min and max values for two variables. I want to draw n random samples from a uniform distribution of these two variables, lying between their min and max values. For example:

min_x = 0
max_x = 10
min_y = 0
max_y = 20

Let's say I draw three samples. These could be:

[(4, 15), (8, 9), (0, 19)] # First value is drawn randomly with uniform probability between min_x and max_x, second value is drawn similarly between min_y and max_y

How can I achieve this with numpy in a simple way?

I've come up with this:

>>> min_x = 0
>>> max_x = 10
>>> min_y = 0
>>> max_y = 20
>>> sample = np.random.random_sample(2)
>>> sample[0] = (sample[0]) * max_x - min_x
>>> sample[1] = (sample[1]) * max_y - min_y
>>> sample
array([ 1.81221794, 18.0091034 ])

but I feel like there should be a simpler solution.

EDIT: Not a duplicate. The answers of the suggested duplicate question deals with integers.

like image 534
Sahand Avatar asked Apr 10 '18 13:04

Sahand


People also ask

How do you generate a random number from a uniform distribution?

The inversion method relies on the principle that continuous cumulative distribution functions (cdfs) range uniformly over the open interval (0,1). If u is a uniform random number on (0,1), then x = F - 1 ( u ) generates a random number x from any continuous distribution with the specified cdf F .

How do you generate random numbers with uniform distribution in Python?

To generate random numbers from the Uniform distribution we will use random. uniform() method of random module. In uniform distribution samples are uniformly distributed over the half-open interval [low, high) it includes low but excludes high interval.

What is the difference between random random and random uniform?

random. random() gives you a random floating point number in the range [0.0, 1.0) (so including 0.0 , but not including 1.0 which is also known as a semi-open range). random. uniform(a, b) gives you a random floating point number in the range [a, b] , (where rounding may end up giving you b ).


2 Answers

The arguments for most of the random generating functions in numpy run on arrays. The following code produces 10 samples where the first column is drawn from a (0, 10) uniform distribution and the second is drawn from a (0, 20).

n = 10
xy_min = [0, 0]
xy_max = [10, 20]
data = np.random.uniform(low=xy_min, high=xy_max, size=(n,2))
print(data)

The output is

[[ 5.93168121,  7.36060232],
 [ 6.0681728 ,  8.83458336],
 [ 3.51412518,  7.86395892],
 [ 5.28704184, 11.2423749 ],
 [ 8.14407888,  6.30980757],
 [ 8.93337281, 13.39148231],
 [ 6.94694921, 19.50003171],
 [ 2.52280804, 13.21572422],
 [ 3.41855383,  2.56327567],
 [ 4.06155783,  3.95026796]]
like image 75
alexdor Avatar answered Sep 30 '22 21:09

alexdor


I think you can just use np.random.uniform, which specifically draws samples from a uniform distribution. It takes the arguments high, low and size, so you can draw 2 samples of size 3 using min_x, max_x, min_y and max_y as your highs and lows, and zip the two together:

list(zip(np.random.uniform(min_x,max_x,3), np.random.uniform(min_y,max_y,3)))
#[(5.3104205843005658, 13.505026912687656), (9.2780870724003979, 7.6835513126639921), (8.0256063658604635, 12.539814624240064)]

Note that the intervals are half-open [low, high) (see linked docs)

like image 20
sacuL Avatar answered Sep 30 '22 20:09

sacuL