Select Language

AI Technology Community

4.10、Python randomライブラリの使用法の詳細

Pythonにはrandomライブラリが付属しており、このライブラリを使っていくつかの数をランダムに生成することができます。通常は、ランダムな実数や整数を生成するために使用されます。

random.random()を使って、0から1の間の実数をランダムに生成することができます。整数を生成したい場合は、random.randint(開始値, 終了値)を使って指定範囲内の整数を取得することができます。

ランダムな整数と実数の生成

得られた値がランダム分布していることをどうやって知ることができるでしょうか?2つの側面から観察することができます。

まず、任意の区間に含まれる数の個数は、その区間の大きさに比例するはずです。例えば、ランダムな実数を生成する場合、0から0.1の区間に含まれる数は10%、0.1から0.6の区間に含まれる数は50%になるはずです。以下のコードを使って検証することができます。

import random
num00_01 = 0
num01_06 = 0
total_num = 10000
while total_num > 0:
    rand_val = random.random()
    if rand_val < 0.1:
        num00_01 = num00_01 + 1
    if 0.6 > rand_val > 0.1:
      num01_06 = num01_06 + 1
    total_num = total_num -1
print(u"0から0.1の間に含まれる数の個数は%dで、割合は%fです" % (num00_01, num00_01/10000.0))
print(u"0.1から0.6の間に含まれる数の個数は%dで、割合は%fです" % (num01_06, num01_06/10000.0))

実行結果は以下の通りです。

$ python rand1.py
0から0.1の間に含まれる数の個数は1004で、割合は0.100400です
0.1から0.6の間に含まれる数の個数は4950で、割合は0.495000です


すべての数が均等に分布している場合、例えば1から100の間のランダムな整数を10000個生成するとき、100個の1、100個の2、...、100個の100というように並ぶと、先ほどの条件を満たしますが、明らかにランダム分布ではありません。

ランダム分布のもう1つの特徴は、各数が出現する平均位置が同じであることです。例えば、すべての1が出現する位置の合計と、すべての10が出現する位置の合計はほぼ同じになり、平均位置は区間の中央になります。上の例では、平均位置は10000/2 = 5000になります。以下では、ランダムな整数を使って、生成されたランダム数がこの条件を満たしているかどうかを確認します。

import random
val_10_num = 0
val_20_num = 0
val_50_num = 0
total_pos_10 = 0
total_pos_20 = 0
total_pos_50 = 0
total_num = 10000
current_pos = 1
while current_pos <= total_num:
   rand_val = random.randint(1, 100)
   if rand_val == 10:
       val_10_num = val_10_num + 1
       total_pos_10 = total_pos_10 + current_pos       
   if rand_val == 20:
       val_20_num = val_20_num + 1
       total_pos_20 = total_pos_20 + current_pos
   if rand_val == 50:
       val_50_num = val_50_num + 1
   total_pos_50 = total_pos_50 + current_pos
   current_pos = current_pos +1
print(u"10が出現する回数は%dで、平均位置は%dです" % (val_10_num, total_pos_10/val_10_num))
print(u"20が出現する回数は%dで、平均位置は%dです" % (val_20_num, total_pos_20/val_20_num))
print(u"50が出現する回数は%dで、平均位置は%dです" % (val_50_num, total_pos_50/val_50_num))

実行結果は以下の通りです。

$ python rand2.py
10が出現する回数は97で、平均位置は4976です
20が出現する回数は104で、平均位置は5124です
50が出現する回数は98で、平均位置は5005です

出現回数はすべて100回に近く、平均位置は5000に近いことがわかります。

実数が出現する区間を0から1以外にしたい場合はどうすればいいでしょうか?平行移動と伸縮を使う方法があります。簡単に言うと、y = ax + bを使います。ここで、xは0から1の間のランダム数で、yはbからa + bの間のランダム数になります。以下の例では、1.5から2.9の間のランダム数を生成します。

import random
start = 1.5
end = 2.9
def generate_random():
    x = random.random()
    y = start + x*(end-start)
    return y
print(generate_random())
print(generate_random())
print(generate_random())
print(generate_random())
print(generate_random())

実行結果は以下の通りです。

$ python rand3.py
2.73776895174
1.99803168825
2.28699864497
2.71552010852
2.88653219406


指定された区間内のランダムな実数を得るには、random.uniform()を直接使うことができます。結果は上の例と同じになります。

>>> import random
>>> random.uniform(1.2, 2.9)
2.6148511677324087
>>> random.uniform(1.2, 2.9)
1.3768844360707853
>>> random.uniform(1.2, 2.9)
1.974822517837854
>>> random.uniform(1.2, 2.9)
2.7001362254339325
>>> random.uniform(1.2, 2.9)
2.469935919913799

その他のランダム形式

もう1つよく使われる関数はrandom.choice()です。この関数はリストを受け取り、入力されたリストからランダムに1つの要素を選んで返します。この関数を使ってサイコロを振るシミュレーションを行うことができます。以下のようになります。

>>> import random              # ランダムライブラリをインポート
>>> dice = [1, 2, 3, 4, 5, 6]  # 出現可能な数は1から6までで、この範囲を超えることはできません
>>> random.choice(dice)        # サイコロを1回振る
5                       # サイコロの目
>>> random.choice(dice)        # サイコロを1回振る
3                       # サイコロの目
>>> random.choice(dice)        # サイコロを1回振る
1                       # サイコロの目
>>> random.choice(dice)        # サイコロを1回振る
2                       # サイコロの目
>>> random.choice(dice)        # サイコロを1回振る
1                       # サイコロの目

もう1つのよく使われる関数はrandom.shuffle()です。この関数は、あるリストの順序をシャッフルするために使用されます。random.shuffle()関数を使ってこのタスクを実行することができます。

>>> import random
>>> a = range(10)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> random.shuffle(a)
>>> a
[7, 9, 4, 2, 6, 1, 8, 3, 0, 5]

この関数は、トランプをシャッフルする動作をシミュレートするために使用することができます。トランプ1組は54枚で、最初は順番に並んでいます。以下では、shuffle()関数を使ってシャッフル機能を実装します。

import random
def init_cards():
    ret = []
    for i in range(1, 13):
        ret.append((i, u'ハート'))
        ret.append((i, u'スペード'))
        ret.append((i, u'ダイヤ'))
        ret.append((i, u'クラブ'))
    ret.append((14, u'大王'))
    ret.append((14, u'小王'))
    return ret
cards = init_cards()
random.shuffle(cards)
for card in cards:
    if card[0] == 14:
  
post
  • 10

    item of content
Pythonにおいて、ディレクトリとファイルは非常に重要で、異なるファイルでは同じ関数や変数を定義しても衝突が起こりません。これはJavaに似ており、CやC++とは明らかに異なります。Pythonはソースコードのレベルでネームスペースを定義していないため、ファイルとパスがimport文と共にネームスペースの役割を果たします。
異なるPythonファイルは異なるモジュールに対応し、同じディレクトリ内の複数のPythonファイルの集合が1つのパッケージとなります。
この章では、読者にPythonのモジュールとパッケージの概念と定義を説明し、合わせてサードパーティのPythonパッケージの様々なインストール方法と使用法を紹介します。