テスト目的で整数のランダムリストを作成したいと思います。数字の分布は重要ではありません。カウントしているのはtimeだけです。乱数の生成は時間のかかる作業ですが、もっと良い方法が必要です。
私の現在のソリューションは次のとおりです。
import random
import timeit
# Random lists from [0-999] interval
print [random.randint(0, 1000) for r in xrange(10)] # v1
print [random.choice([i for i in xrange(1000)]) for r in xrange(10)] # v2
# Measurement:
t1 = timeit.Timer('[random.randint(0, 1000) for r in xrange(10000)]', 'import random') # v1
t2 = timeit.Timer('random.sample(range(1000), 10000)', 'import random') # v2
print t1.timeit(1000)/1000
print t2.timeit(1000)/1000
v2はv1よりも高速ですが、このような大規模では機能していません。次のエラーが発生します。
ValueError:母集団より大きいサンプル
その規模で機能する高速で効率的なソリューションはありますか?
アンドリュース:0.000290962934494
ニブラー:0.0058455221653
ケニーTM:0.00219276118279
NumPyが来て、見て、征服しました。
あなたが望むものが完全に明確ではありませんが、私は numpy.random.randint を使用します:
import numpy.random as nprnd
import timeit
t1 = timeit.Timer('[random.randint(0, 1000) for r in xrange(10000)]', 'import random') # v1
### Change v2 so that it picks numbers in (0, 10000) and thus runs...
t2 = timeit.Timer('random.sample(range(10000), 10000)', 'import random') # v2
t3 = timeit.Timer('nprnd.randint(1000, size=10000)', 'import numpy.random as nprnd') # v3
print t1.timeit(1000)/1000
print t2.timeit(1000)/1000
print t3.timeit(1000)/1000
私のマシンに与える:
0.0233682730198
0.00781716918945
0.000147947072983
Randintはrandom.sampleとはvery異なることに注意してください(あなたのケースで動作するためには、1,000から10,000をコメンテーターは指摘しました-あなたが本当に0から1,000までそれらを望むなら、10で割ることができます)。
そして、あなたがどの分布を得ているのか本当に気にしないなら、あなたはあなたの問題をあまりよく理解していないか、または乱数である可能性があります。
すべてのランダムメソッドはrandom.random()
を呼び出すことになります。そのため、最良の方法は直接呼び出すことです。
[int(1000*random.random()) for i in xrange(10000)]
例えば、
random.randint
はrandom.randrange
を呼び出します。random.randrange
には、istart + istep*int(self.random() * n)
を返す前に範囲をチェックするためのオーバーヘッドがあります。もちろん、NumPyははるかに高速です。
パフォーマンスに関するあなたの質問は重要ではありません。両方の機能は非常に高速です。コードの速度は、乱数を使用してdoで決定されます。
ただし、これら2つの関数のbehaviourの違いを理解することが重要です。 1つは置換ありでランダムサンプリングを行い、もう1つは置換なしでランダムサンプリングを行います。
まず、randrange(0,1000)
ではなく、randint(0,999)
またはrandint(0,1000)
を使用する必要があります。 randint
の上限は包括的です。
効率的には、randint
はrandrange
を呼び出すrandom
の単なるラッパーなので、random
を使用するだけです。また、xrange
ではなく、sample
の引数としてrange
を使用します。
使用できます
[a for a in sample(xrange(1000),1000) for _ in range(10000/1000)]
sample
を使用して範囲内で10,000個の数値を10回生成します。
(もちろん、これはNumPyに勝るものではありません。)
$ python2.7 -m timeit -s 'from random import randrange' '[randrange(1000) for _ in xrange(10000)]'
10 loops, best of 3: 26.1 msec per loop
$ python2.7 -m timeit -s 'from random import sample' '[a%1000 for a in sample(xrange(10000),10000)]'
100 loops, best of 3: 18.4 msec per loop
$ python2.7 -m timeit -s 'from random import random' '[int(1000*random()) for _ in xrange(10000)]'
100 loops, best of 3: 9.24 msec per loop
$ python2.7 -m timeit -s 'from random import sample' '[a for a in sample(xrange(1000),1000) for _ in range(10000/1000)]'
100 loops, best of 3: 3.79 msec per loop
$ python2.7 -m timeit -s 'from random import shuffle
> def samplefull(x):
> a = range(x)
> shuffle(a)
> return a' '[a for a in samplefull(1000) for _ in xrange(10000/1000)]'
100 loops, best of 3: 3.16 msec per loop
$ python2.7 -m timeit -s 'from numpy.random import randint' 'randint(1000, size=10000)'
1000 loops, best of 3: 363 usec per loop
しかし、あなたは数字の分布を気にしないので、なぜ単に使用しないのですか:
range(1000)*(10000/1000)
?