Non-repetitive random number in numpy Non-repetitive random number in numpy numpy numpy

Non-repetitive random number in numpy


numpy.random.Generator.choice offers a replace argument to sample without replacement:

from numpy.random import default_rngrng = default_rng()numbers = rng.choice(20, size=10, replace=False)

If you're on a pre-1.17 NumPy, without the Generator API, you can use random.sample() from the standard library:

print(random.sample(range(20), 10))

You can also use numpy.random.shuffle() and slicing, but this will be less efficient:

a = numpy.arange(20)numpy.random.shuffle(a)print a[:10]

There's also a replace argument in the legacy numpy.random.choice function, but this argument was implemented inefficiently and then left inefficient due to random number stream stability guarantees, so its use isn't recommended. (It basically does the shuffle-and-slice thing internally.)


I think numpy.random.sample doesn't work right, now. This is my way:

import numpy as npnp.random.choice(range(20), 10, replace=False)


Years later, some timeits for choosing 40000 out of 10000^2(Numpy 1.8.1, imac 2.7 GHz):

import randomimport numpy as npn = 10000k = 4np.random.seed( 0 )%timeit np.random.choice( n**2, k * n, replace=True )  # 536 µs ± 1.58 µs%timeit np.random.choice( n**2, k * n, replace=False ) # 6.1 s ± 9.91 ms# https://docs.scipy.org/doc/numpy/reference/random/index.htmlrandomstate = np.random.default_rng( 0 )%timeit randomstate.choice( n**2, k * n, replace=False, shuffle=False )  # 766 µs ± 2.18 µs%timeit randomstate.choice( n**2, k * n, replace=False, shuffle=True )   # 1.05 ms ± 1.41 µs%timeit random.sample( range( n**2 ), k * n )          # 47.3 ms ± 134 µs

(Why choose 40000 out of 10000^2 ?To generate largescipy.sparse.randommatrices -- scipy 1.4.1 uses np.random.choice( replace=False ), slooooow.)

Tip of the hat to numpy.random people.