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?
2 Answers
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])