如何在 numpy 中生成非重复随机数?
list = np.random.random_integers(20,size=(10))
如何在 numpy 中生成非重复随机数?
list = np.random.random_integers(20,size=(10))
numpy.random.Generator.choice
提供了一个replace
无需替换的 sample 的论点:
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]
replace
在 legacy函数中还有一个参数numpy.random.choice
,但是这个参数实现效率低,然后由于随机数流稳定性保证而效率低下,因此不推荐使用它。(它基本上在内部进行洗牌和切片。)
一些时间安排:
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
这numpy.random.Generator.choice
就是你通常想要的,除了非常小的输出大小/ k
。
我觉得numpy.random.sample
现在不行 这是我的方式:
import numpy as np
np.random.choice(range(20), 10, replace=False)
多年后,从 10000^2(Numpy 1.8.1,imac 2.7 GHz)中选择 40000 的一些时间:
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.sparse.random
矩阵——scipy 1.4.1 使用np.random.choice( replace=False )
,slooooow。)
向 numpy.random 人致敬。
您也可以通过排序获得此信息:
random_numbers = np.random.random([num_samples, max_int])
samples = np.argsort(random_numbers, axis=1)
可以使用 Python 设置列表转换。可以得到 0 到 20 之间的 10 个随机不重复数:
import random
numbers=set()
while(len(numbers)<10):
numbers.add(random.randint(0,20))
numbers=list(numbers)
random.shuffle(numbers)
print(numbers)
只需生成一个包含所需数字范围的数组,然后通过重复将随机数字与数组中的第 0 个元素交换来打乱它们。这会产生一个不包含重复值的随机序列。