Generate each column of the numpy array with random number from different range

Viewed 3445

How to generate a numpy array such that each column of the array comes from a uniform distribution within different ranges efficiently? The following code uses two for loop which is slow, is there any matrix-style way to generate such array faster? Thanks.

import numpy as np
num = 5
ranges = [[0,1],[4,5]]
a = np.zeros((num, len(ranges)))
for i in range(num):
    for j in range(len(ranges)):
        a[i, j] = np.random.uniform(ranges[j][0], ranges[j][1])
2 Answers

What you can do is produce all random numbers in the interval [0, 1) first and then scale and shift them accordingly:

import numpy as np
num = 5
ranges = np.asarray([[0,1],[4,5]])
starts = ranges[:, 0]
widths = ranges[:, 1]-ranges[:, 0]
a = starts + widths*np.random.random(size=(num, widths.shape[0]))

So basically, you create an array of the right size via np.random.random(size=(num, widths.shape[0])) with random number between 0 and 1. Then you scale each value by a factor corresponding to the width of the interval that you actually want to sample. Finally, you shift them by starts to account for the different starting values of the intervals.

numpy.random.uniform will broadcast its arguments, it can generate the desired samples by passing the following arguments:

  • low: the sequence of low values.
  • high: the sequence of high values.
  • size: a tuple like (num, m), where m is the number of ranges and num the number of groups of m samples to generate.

For example:

In [23]: num = 5

In [24]: ranges = np.array([[0, 1], [4, 5], [10, 15]])

In [25]: np.random.uniform(low=ranges[:, 0], high=ranges[:, 1], size=(num, ranges.shape[0]))
Out[25]: 
array([[  0.98752526,   4.70946614,  10.35525699],
       [  0.86137374,   4.22046152,  12.28458447],
       [  0.92446543,   4.52859103,  11.30326391],
       [  0.0535877 ,   4.8597036 ,  14.50266784],
       [  0.55854656,   4.86820001,  14.84934564]])
Related