乱数

Python には何通りかの乱数が用意されています。ここではシミュレーション用の乱数を説明します。パスワード生成のためには安全な乱数をご覧ください。

標準ライブラリ random

random は標準ライブラリですのでインストールする必要はありません。Mersenne Twister が使われています。

import random

random.random()  # 引数をとらない。区間 [0,1) の1個の乱数を返す
random.randrange(1, 7)  # 1から6までの整数の乱数
random.randint(1, 6)    # 1から6までの整数の乱数

本格的なシミュレーションで大量の乱数を必要とする場合には次の NumPy による方法を使います。

ライブラリ NumPy

numpy.random を使います。

古い方法

Mersenne Twister が使われています。

import numpy as np

np.random.random(10)             # 0以上1未満の一様乱数10個
np.random.randint(1, 7, size=10) # 1以上7未満の整数の乱数10個

新しい方法

2013年にリリースされた NumPy 1.17.0 からは Generator を使った新しいインターフェースが推奨されています(NumPy のバージョンは np.__version__ でわかります)。デフォルトのアルゴリズムは PCG64 です。これは次のようにして使います:

import numpy as np

rng = np.random.default_rng(20200102) # seedの設定(空も可)
rng.random(10)                # 0以上1未満の一様乱数10個
rng.standard_normal(10)       # 標準正規分布の乱数10個
rng.integers(1, 7, size=10)   # 1以上7未満の整数の乱数10個

上の例のように「タネ(seed)」を与えるのがシミュレーションでの推奨です。同じタネからは同じ乱数列が生成されますので,あとで結果を再現できます。ゲームなどでは rng = np.random.default_rng() のように空にすると,再現性のない(毎回異なる)乱数列が得られます。

例えばモンテカルロ法で円周率を求めるには次のようにします:

import matplotlib.pyplot as plt

N = 10000
x = rng.random(N)
y = rng.random(N)
c = x*x + y*y < 1
plt.scatter(x, y, c=c)
plt.axis('scaled')
print('pi =', 4 * np.sum(c) / N)

ランダムウォークの例です:

N = 1000
x = np.cumsum(rng.random(N) - 0.5)
y = np.cumsum(rng.random(N) - 0.5)
plt.plot(x, y)
plt.axis('equal')

硬貨投げのシミュレーションは rng.integers(0, 2, size=100) のようにできます。表の枚数は np.sum(rng.integers(0, 2, size=100)) です。これを何回もやってヒストグラムを描いてみましょう。

a = [np.sum(rng.integers(0, 2, size=100)) for _ in range(10000)]
plt.hist(a)

Last modified: