Python 標準ライブラリ random 擬似乱数
Publish date: 2021-04-10
ライブラリrandomを使うとPythonで乱数を使うことができます。
整数値の乱数を取得する例
import random
random.seed(0)
random.randrange(5) # => 3
ranomの内部状態を設定するメソッド
再現性のある結果が欲しい場合random.seed(0)
等で乱数のシードを固定しておく。
seed(a=None, version=2) 乱数生成の初期化
random.seed()
random.seed(0)
getstate() 乱数生成器の内部状態のオブジェクト取得
state = random.getstate()
setstate(state) 乱数生成器の内部状態の設定
state = random.getstate()
random.setstate(state)
度数分布のグラフを出力する準備
以降で乱数の出力結果をヒストグラムでみたいので以下の関数を定義しておく。
import matplotlib.pyplot as plt
def hist_plot(data, bins, xticks):
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.hist(data, bins=bins)
ax.set_xticks(xticks)
整数の乱数
randrange(stop) 0以上~stop未満の整数の乱数
random.randrange(10) # => 0~9の整数
hist_plot([random.randrange(10) for x in range(1000)], 10 , range(0,10))
randrange(start, stop[, step]) range(start, stop[, step])の範囲にある整数の乱数
random.randrange(2, 9) # => 2~8の整数
hist_plot([random.randrange(2, 9) for x in range(1000)], 7 , range(2,9))
random.randrange(2, 9, 3) # => 2~8の整数3つおき(=> 2, 5, 8)
hist_plot([random.randrange(2, 9, 3) for x in range(1000)], 7 , range(2,9))
randint(a, b) a<=N<=bの整数の乱数 randrange(a, b+1)
random.randint(2,8) # => 2~8の整数
hist_plot([random.randint(2,8) for x in range(1000)], 7 , range(2,9))
getrandbits(k) kビットで表現できる整数の乱数
random.getrandbits(3) # => 0b000~0b111
[random.getrandbits(3) for x in range(10)]
# => [7, 7, 0, 2, 5, 3, 1, 2, 6, 2]
[bin(random.getrandbits(3)) for x in range(10)]
# => ['0b110', '0b0', '0b110', '0b1', '0b111', '0b11', '0b11', '0b0', '0b0', '0b101']
hist_plot([random.getrandbits(3) for x in range(1000)], 8 , range(0,8))
ランダムな要素の取り出し
choice(seq) シーケンスからランダムに要素取得
random.choice('abc') # => 'a', 'b', 'c'
random.choice([1, 3, 7, 1]) # => 1, 3, 7
choices(population, weights=None, *, cum_weights=None, k=1) 重複ありの要素抽出
重みweights,cum_weightsを付けてシーケンスからk個を取り出す。 weightsは相対的な比率で、cum_weightsは累積的な値で重みを指定する。
population = [1, 2, 3]
random.choices(population) # => [1], [2], [3]
random.choices(population, k=2) # => [1,1], [1,2]等
#重みづけで取得(相対的)
random.choices(population, weights=[60,10,20]) # => [1], [2], [3]
hist_plot( [ random.choices(population, weights=[60,10,20])[0] for x in range(1000) ], 3 , range(1,3))
#重みづけで取得(累積的)
random.choices(population, cum_weights=[60,70,90]) # => [1], [2], [3]
hist_plot( [ random.choices(population, cum_weights=[60,70,90])[0] for x in range(1000) ], 3 , range(1,3))
shuffle(x) シーケンスのシャッフル (ミュータブルなシーケンスそのものの並び替え)
items = list(range(10))
random.shuffle(items)
items # => [6, 3, 8, 4, 5, 1, 0, 2, 7, 9]
sample(population, k, *, counts=None) 母集団からk個の要素のリストを作成
countsで各要素の出現回数を指定できる。
items = list(range(10))
random.sample(items,2) # => [3, 5]等
# countsの指定で母集団各要素の選択回数を指定できる
random.sample([1,2,3], 2, counts=[5,1,4]) # => [1, 3]等
# 以下と同じ
random.sample([1,1,1,1,1,2,3,3,3,3], 2) # => [1, 3]等
浮動小数の乱数
random() 0以上1未満の小数 [0.0, 1.0)
random.random() # => 0.8444218515250481
hist_plot([random.random() for x in range(10000) ], 50 , [0.1*x for x in range(0,11)])
random.uniform(a, b) a以上b以下 [a,b](またはb以上a以下b [b,a])の小数
random.uniform(3, 8) # => 7.323203944644748
hist_plot([random.uniform(3, 8) for x in range(10000) ], 50 , [0.1*x+3.0 for x in range(0,11)])
triangular(low, high, mode) low以上high以下で最頻値modeの小数
# デフォルトはlow=0,high=1,mode=(low+high)/2
random.triangular() # = > 0.5811208765762167
hist_plot([random.triangular() for x in range(10000) ], 50 , [0.1*x for x in range(0,11)])
hist_plot([random.triangular(3,5) for x in range(10000) ], 50 , [0.2*x+3.0 for x in range(0,11)])
hist_plot([random.triangular(3,5,4.5) for x in range(10000) ], 50 , [0.2*x+3.0 for x in range(0,11)])
betavariate(alpha, beta) ベータ分布(beta distribution)
random.betavariate(2, 2) # = > 0.5395630434906871
hist_plot([random.betavariate(2, 2) for x in range(10000) ], 50 , [0.1*x for x in range(0,11)])
hist_plot([random.betavariate(0.5, 0.5) for x in range(10000) ], 50 , [0.1*x for x in range(0,11)])
hist_plot([random.betavariate(5, 1) for x in range(10000) ], 50 , [0.1*x for x in range(0,11)])
hist_plot([random.betavariate(1, 3) for x in range(10000) ], 50 , [0.1*x for x in range(0,11)])
hist_plot([random.betavariate(2, 5) for x in range(10000) ], 50 , [0.1*x for x in range(0,11)])
expovariate(lambd) 指数分布 (exponential distribution)
random.expovariate(10) # = > 0.0443397045417289
hist_plot([random.expovariate(10) for x in range(10000) ], 50 , [x*0.1 for x in range(0,10)])
hist_plot([random.expovariate(1) for x in range(10000) ], 50 , [x for x in range(0,10)])
hist_plot([random.expovariate(0.1) for x in range(10000) ], 50 , [x*10 for x in range(0,10)])
gammavariate(alpha, beta) ガンマ分布(gamma distribution)
random.gammavariate(9, 0.5) # = > 4.555121091194622
hist_plot([random.gammavariate(9, 0.5) for x in range(10000) ], 50 , [x for x in range(0,10)])
hist_plot([random.gammavariate(1, 2) for x in range(10000) ], 50 , [x for x in range(0,10)])
gauss(mu, sigma) ガウス分布(正規分布) (Gaussian distribution)
muは平均、 sigma は標準偏差。後にでてくるnormalvariate()
よりも少し高速。
random.gauss(0, 1) # = > 0.31367378413426494
hist_plot([random.gauss(0,1) for x in range(10000) ], 50 , [x for x in range(-5,6)])
hist_plot([random.gauss(2,1) for x in range(10000) ], 50 , [x for x in range(-5,6)])
lognormvariate(mu, sigma) 対数正規分布 (log-normal distribution)
random.lognormvariate(0, 0.01) # = >1.0042626445054275
hist_plot([random.lognormvariate(0,0.01) for x in range(10000) ], 50 , [x for x in range(0,4)])
hist_plot([random.lognormvariate(0,0.1) for x in range(10000) ], 50 , [x for x in range(0,4)])
hist_plot([random.lognormvariate(0,0.5) for x in range(10000) ], 50 , [x for x in range(0,4)])
hist_plot([random.lognormvariate(0,1) for x in range(10000) ], 50 , [x for x in range(0,4)])
normalvariate(mu, sigma) 正規分布(ガウス分布) (normal distribution)
gauss()
と同様。
random.normalvariate(0, 1) # = > -0.3401010161409137
hist_plot([random.normalvariate(0,1) for x in range(10000) ], 50 , [x for x in range(-5,6)])
hist_plot([random.normalvariate(2,1) for x in range(10000) ], 50 , [x for x in range(-5,6)])
gauss()の方がnormalvariate()よりも少しだけ高速。
%timeit -r 7 -n 100000 random.gauss(0,1)
# => 853 ns ± 162 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit -r 7 -n 100000 random.normalvariate(0,1)
# => 985 ns ± 172 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
vonmisesvariate(mu, kappa) フォン・ミーゼス分布 (von Mises distribution)
0から2*piラジアンまでの角度方向の分布。平均muが一番多くなる。kappaは濃度パラメータで、ゼロだと一様な分布。
import math
random.vonmisesvariate(0, 1) # = > 6.087179444930305
hist_plot([random.vonmisesvariate(0,0) for x in range(10000) ], 50 , [x for x in range(0,7)])
hist_plot([random.vonmisesvariate(0,1) for x in range(10000) ], 50 , [x for x in range(0,7)])
hist_plot([random.vonmisesvariate(0,2) for x in range(10000) ], 50 , [x for x in range(0,7)])
hist_plot([random.vonmisesvariate(math.pi,0) for x in range(10000) ], 50 , [x for x in range(0,7)])
hist_plot([random.vonmisesvariate(math.pi,1) for x in range(10000) ], 50 , [x for x in range(0,7)])
hist_plot([random.vonmisesvariate(math.pi,2) for x in range(10000) ], 50 , [x for x in range(0,7)])
paretovariate(alpha) パレート分布 (Pareto distribution)
def hist_plot_rim(data, bins, xticks, xlim):
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.hist(data, bins=bins)
ax.set_xticks(xticks)
ax.set_xlim(*xlim)
random.paretovariate(10) #=> 1.0005914562417035
hist_plot_rim([random.paretovariate(1) for x in range(10000) ], 200 , [0.5*x+1 for x in range(0,10)], [0.5,3])
hist_plot_rim([random.paretovariate(2) for x in range(10000) ], 200 , [0.5*x+1 for x in range(0,10)], [0.5,3])
hist_plot_rim([random.paretovariate(3) for x in range(10000) ], 200 , [0.5*x+1 for x in range(0,10)], [0.5,3])
hist_plot_rim([random.paretovariate(5) for x in range(10000) ], 200 , [0.5*x+1 for x in range(0,10)], [0.5,3])
hist_plot_rim([random.paretovariate(10) for x in range(10000) ],200 , [0.5*x+1 for x in range(0,10)], [0.5,3])
weibullvariate(alpha, beta) ワイブル分布 (Weibull distribution)
alphaはスケールパラメータ、betaは形状パラメータ。
hist_plot([random.weibullvariate(1, 1) for x in range(10000) ], 50 , [x*0.1 for x in range(0,10)])
hist_plot([random.weibullvariate(1, 2) for x in range(10000) ], 50 , [x*0.1 for x in range(0,10)])
その他のメソッド
randbytes(n) ランダムなバイト生成
random.randbytes(5) # => b'\xcd\x07,\xd8b'