麻木中的非重复随机数

我如何产生非重复的随机数在麻木?

list = np.random.random_integers(20,size=(10))
136993 次浏览

只需生成一个包含所需范围的数字的数组,然后通过重复交换数组中第0个元素的随机数来洗牌。这会产生一个不包含重复值的随机序列。

numpy.random.Generator.choice 提供了一个 replace参数,不需要更换:

from numpy.random import default_rng


rng = default_rng()
numbers = rng.choice(20, size=10, replace=False)

如果你使用的是1.17之前的 NumPy,没有 Generator API,你可以从标准库中使用 random.sample():

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

你也可以使用 numpy.random.shuffle()和切片,但是效率会降低:

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

在遗留的 numpy.random.choice函数中也有一个 replace参数,但是由于随机数流稳定性保证,这个参数的实现效率不高,因此不推荐使用它。(它基本上是在内部进行洗牌和切片。)

一些时机:

import timeit
print("when output size/k is large, np.random.default_rng().choice() is far far quicker, even when including time taken to create np.random.default_rng()")
print(1, timeit.timeit("rng.choice(a=10**5, size=10**4, replace=False, shuffle=False)", setup="import numpy as np; rng=np.random.default_rng()", number=10**3)) #0.16003450006246567
print(2, timeit.timeit("np.random.default_rng().choice(a=10**5, size=10**4, replace=False, shuffle=False)", setup="import numpy as np", number=10**3)) #0.19915290002245456


print(3, timeit.timeit("random.sample( population=range(10**5), k=10**4)", setup="import random", number=10**3))   #5.115292700007558


print("when output size/k is very small, random.sample() is quicker")
print(4, timeit.timeit("rng.choice(a=10**5, size=10**1, replace=False, shuffle=False)", setup="import numpy as np; rng=np.random.default_rng()", number=10**3))  #0.01609779999125749
print(5, timeit.timeit("random.sample( population=range(10**5), k=10**1)", setup="import random", number=10**3))  #0.008387799956835806

因此,除了非常小的输出大小/k之外,numpy.random.Generator.choice是您通常希望使用的值。

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

import random
import numpy as np


n = 10000
k = 4
np.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.html
randomstate = 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

(为什么在10000 ^ 2中选择40000? 生成大的 很少,很稀疏,很随意 矩阵—— scipy 1.4.1使用 np.random.choice( replace=False ),slow。)

Tip of the hat to numpy.random people.

我认为 numpy.random.sample现在不能正常工作。这是我的方法:

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

你也可以通过排序得到这个结果:

random_numbers = np.random.random([num_samples, max_int])
samples = np.argsort(random_numbers, axis=1)

Python set-list conversion can be used. 10 random non repetitive numbers between 0 and 20 can be obtained as:

import random
numbers=set()
while(len(numbers)<10):
numbers.add(random.randint(0,20))


numbers=list(numbers)
random.shuffle(numbers)
print(numbers)