如何在numpy中生成不重复的随机数?
list = np.random.random_integers(20,size=(10))
如何在numpy中生成不重复的随机数?
list = np.random.random_integers(20,size=(10))
numpy.random.Generator.choice
函数提供了一个 replace
参数,可以实现无重复采样:
from numpy.random import default_rng
rng = default_rng()
numbers = rng.choice(20, size=10, replace=False)
如果您使用的是1.17版本之前且没有Generator API的NumPy,则可以使用标准库中的random.sample()函数: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
因此,numpy.random.Generator.choice
通常是最理想的选择,除非输出大小/k
非常小。
我认为目前numpy.random.sample
没有正常工作。这是我的方法:
import numpy as np
np.random.choice(range(20), 10, replace=False)
choice
函数的第一个参数中,可以用 n
代替 range(n)
或 arange(n)
,例如 choice(20, 10, replace=False)
。这样做是等价的。请注意,不要改变原意,并尽量使翻译更通俗易懂。 - Josh Bodea
,np.random.choice(a, size, replace=False)
的速度非常慢 - 在我的计算机上,a=1M 时大约需要30毫秒。 - Matthew Rahtzn
时出现时间和内存问题,请使用numpy.random.Generator.choice
(从numpy v1.17开始可用)。 - benbo几年后,在选择10000的平方中的40000个数字时(使用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
np.random.choice( replace=False )
,速度非常慢。
向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个元素交换来对它们进行洗牌。这样就可以产生一个不包含重复值的随机序列。