1. ホーム
  2. random

[解決済み] numpyの非繰り返し乱数

2022-09-23 02:39:13

質問

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以前の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 の引数は、レガシーな 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 .