Sahand
Sahand

Reputation: 8360

How to draw 2D random uniform samples from two ranges

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.

Upvotes: 7

Views: 14775

Answers (2)

alexdor
alexdor

Reputation: 866

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]]

Upvotes: 22

sacuL
sacuL

Reputation: 51335

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)

Upvotes: 3

Related Questions