乱数の生成

乱数の生成

疑似乱数の生成

 Python標準ライブラリの randomモジュールには様々な種類の疑似乱数を生成する関数が用意されています。疑似乱数とは seed によって値が確定的に決まる数字の列で、0 ~ 9 が均一の割合で分布しています。疑似乱数は一定の周期をもちますが、この周期が長いほど高品質の疑似乱数であることを意味します。Pythonではメルセンヌツイスタ (Mersenne twister) とよばれる周期 2**19937-1 の生成器(ジェネレータ)を使用して疑似乱数を作りだしていきます。
 

浮動小数点数型の乱数

random.random()

 random.random() は 0.0 以上、1 未満の 浮動小数点数型の一様乱数を生成します。

# https://python.atelierkobato.com/random/

# randomモジュールをインポート
import random

# 0~1の乱数を3個生成
for k in range(3):
    x = random.random()
    print(x)
0.8792205530080683
0.0006700208569692112
0.04848366552796579

 

random.uniform(a, b)

 random.uniform(a, b) は a ≦ b であるときは、a ≦ N ≦ b の範囲で浮動小数点数型の一様乱数 N を返します。a > b であるときは、b ≦ N ≦ a の範囲で浮動小数点数型の乱数 N を返します。

# https://python.atelierkobato.com/random/

# randomモジュールをインポート
import random

# 1~10の乱数を3個生成
for k in range(3):
    x = random.uniform(1, 10)
    print(x)
4.672361143198837
2.7458475789026497
7.883862872788563

 

整数型の乱数

random.randrange(start, stop [, step])

 random.randrange(start, stop [, step]) は start から stop-1 まで step 刻みで並んだ数字の中から1つをランダムに選んで返します。たとえば
 

x = random.randrange(1, 16, 2)

と記述した場合、1 から 15 まで 2 刻みで並んだ数字
 

1, 3, 5, 7, 9, 11, 13, 15

の中から1つを無作為に選んで x に格納します。実際には、この関数は range(start, stop, step) で生成された数字のシーケンスから1つの要素を抜き出すという処理を行なっています。

# https://python.atelierkobato.com/random/

# randomモジュールをインポート
import random

# 0~9 の整数乱数を生成
a = random.randrange(10)

# 1~9 の整数乱数を生成
b = random.randrange(1, 10)

# 1~9 の奇数乱数を生成
c = random.randrange(1, 10, 2)

my_list = [a, b, c]

print(my_list)
[8, 1, 5]

 

random.randint(a, b)

 random.randint(a, b) は、a ≦ N ≦ b の範囲で無作為な整数 N を返します。この関数は randrange(a, b+1) のエイリアスです。すなわち、実際にはこの関数の内部で randrange() に引数 a と b+1 を渡して呼び出すという処理を行なっています。引数の指定の仕方が randrange() とは異なっていることに注意してください。

# https://python.atelierkobato.com/random/

# randomモジュールをインポート
import random

# 空白のリストを用意
my_list = []

# 1~100の乱数を5個生成してリストの要素に追加
for k in range(5):
    x = random.randint(1, 100)
    my_list.append(x)

print(my_list)
[38, 44, 98, 83, 34]

 

ジェネレータの初期化と seed の固定

 randomモジュールのジェネレータ(メルセンヌツイスタ)は seed とよばれる初期値をもとに疑似乱数列を生成しています。seed は「種」という意味の英語です(数字を次々と生み出すのでこのようによばれています)。seed値が与えられると疑似乱数列は一意に定まります(つまり疑似乱数列 R は seed の関数 R(seed) です)。random.seed(a) を使うと、この seed値を固定してジェネレータを初期化することができます。具体例を下のサンプルコードで説明します。

# https://python.atelierkobato.com/random/

# randomモジュールをインポート
import random

# 疑似乱数ジェネレータを初期化して乱数シードを固定
random.seed(1)

# 1~10の乱数を3個生成
for k in range(3):
    x = random.random()
    print(x)

# 1行開ける
print("")

# 疑似乱数ジェネレータを初期化して乱数シードを固定
random.seed(1)

# 1~10の乱数を3個生成
for k in range(3):
    x = random.random()
    print(x)
0.13436424411240122
0.8474337369372327
0.763774618976614

0.13436424411240122
0.8474337369372327
0.763774618976614

 最初の random.seed(1) という記述によって、次の for文では seed を 1 として
 

0.134364244112401
0.847433736937232
0.763774618976614

というように乱数を順に生成(ジェネレート)しています。そのあとに、もう一度 random.seed(1) と記述することによって、ジェネレータが初期化され、次の for文で再び seed = 1 の乱数列の 1 番目から
 

0.134364244112401
0.847433736937232
0.763774618976614

というように数字が並びます。random.seed(a) の引数 a が省略された場合には、seed として現在のシステム時刻が指定されます。
 

内包表記を用いた乱数リストの作成

 いくつかの乱数をまとめて作りたいケースも多いはずです。先ほどの randint() のサンプルコードのように for文を使っても可能ですが、リスト内包表記 (comprehention) を使うと、たった1行で乱数リストをつくることができます。

# https://python.atelierkobato.com/random/

# randomモジュールをインポート
import random

# 0 から 9 までの整数乱数のリストを作成
num_list = [random.randrange(10) for i in range(10)]

print(num_list)
[5, 8, 5, 0, 3, 9, 8, 8, 2, 9]

 

NumPy 乱数配列の生成

 NumPy の random モジュールには乱数を要素とする配列を生成するための関数が用意されています。

numpy.random.rand()

 numpy.random.rand() は 0 以上 1 未満の一様乱数を要素にもつ配列を返します。

 rand(d0, d1, ..., dn)

 引数には配列の形を指定します。たとえば、2, 3 を渡すと、2行3列の乱数配列を返します。

import numpy as np

# seedを設定
np.random.seed(10)

# 2行3列の乱数配列
x = np.random.rand(2, 3)

print(x)
[[0.77132064 0.02075195 0.63364823]
 [0.74880388 0.49850701 0.22479665]]

 

numpy.random.uniform()

 numpy.random.uniform() は指定した範囲内の一様乱数を要素にもつ配列を返します。

 numpy.random.uniform(low=0.0, high=1.0, size=None)

 引数の low は乱数の下限値、high は乱数の上限値です。
 size で戻り値の配列の形状を指定することもできます。

import numpy as np

# seedを設定
np.random.seed(11)

# 1~5の乱数を要素にもつ2×2サイズの配列を生成 
x = np.random.uniform(1, 5, (2, 2))

print(x)
[[1.72107876 1.07790097]
 [2.85287411 3.89973572]]

 

numpy.random.randint()

 numpy.random.randint() は指定範囲内で整数型の一様乱数配列を返します。

 numpy.random.randint(low, high=None, size=None, dtype='l')

 引数の low は乱数の下限値、high は乱数の上限値です。
 size で戻り値の配列の形状を指定することもできます。

import numpy as np

# seedを設定
np.random.seed(10)

# 1~9の一様整数乱数を要素にもつ3×3配列を生成
x = np.random.randint(1, 9, (3, 3))

print(x)
[[2 6 5]
 [8 1 2]
 [4 5 2]]