115

numpyで非反復乱数を生成するにはどうすればよいですか?

list = np.random.random_integers(20,size=(10))
4

6 に答える 6

143

numpy.random.Generator.choicereplace置換なしでサンプリングする引数を提供します:

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))

and slicingを使用することもできます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です。

于 2011-12-14T14:03:02.730 に答える
127

numpy.random.sample今はうまくいかないと思います。これが私のやり方です:

import numpy as np
np.random.choice(range(20), 10, replace=False)
于 2014-08-07T05:24:56.560 に答える
6

数年後、10000 ^ 2から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

(なぜ10000 ^ 2から40000を選択するのですか?大きな scipy.sparse.random 行列を生成するには-scipy 1.4.1はnp.random.choice( replace=False )slooooowを使用します。)

numpy.randomの人々への帽子のヒント。

于 2011-12-14T14:08:51.147 に答える
-3

必要な範囲の数値を含む配列を生成し、ランダムな数値を配列の 0 番目の要素と繰り返し入れ替えてシャッフルします。これにより、重複する値を含まないランダムなシーケンスが生成されます。

于 2011-12-14T13:59:33.637 に答える