Reputation: 2079
I want to generate N random integers, where the first integer is uniformly chosen from 0..N, the second is uniformly chosen from 0..(N-1), the third from 0..(N-2), and so on. Is there a way to do this quickly in numpy, without incurring the cost of performing a separate numpy call N times?
Upvotes: 0
Views: 375
Reputation: 114781
You can pass arrays as the arguments to the integers
method of numpy's random generator class. The arguments will broadcast, and generate the appropriate values.
For example,
In [17]: import numpy as np
In [18]: rng = np.random.default_rng()
In [19]: N = 16
In [20]: rng.integers(0, np.arange(N, 0, -1))
Out[20]: array([13, 10, 11, 11, 9, 8, 3, 0, 2, 5, 3, 1, 0, 2, 0, 0])
Note that the upper value given to the integers
method is excluded, so if the ranges that you stated are inclusive, you'll have to adjust the arange
arguments appropriately:
In [24]: rng.integers(0, np.arange(N+1, 1, -1))
Out[24]: array([ 6, 9, 11, 11, 7, 2, 5, 5, 8, 7, 5, 5, 4, 0, 1, 0])
Upvotes: 1
Reputation: 150735
We can sample random numbers uniformly in (0,1)
and scale, then convert to int:
N = 10
np.random.seed(10)
randoms = np.random.rand(N)
(randoms * np.arange(1,N+1)).astype(int)
Output:
array([0, 0, 1, 2, 2, 1, 1, 6, 1, 0])
Upvotes: 1