Skip to content

Python Random:乱数、選択、サンプルの生成

Updated on

ランダムデータの生成はプログラミングの基本です -- プレイリストのシャッフルやアンケート回答者のサンプリングから、モンテカルロシミュレーションやテストデータセットの作成まで。しかし、Pythonのrandomモジュールには数十の関数があり、間違った関数を使いがちです。整数が必要な時にrandom.random()を呼んだり、複数のユニークな要素が必要な時にchoice()を使ったり、randomが暗号学的に安全でないことを忘れると、微妙なバグやセキュリティの脆弱性につながります。

Pythonのrandomモジュールは、擬似乱数生成のための包括的なツールキットを提供します。このガイドでは、よく使う関数を、いつ使うべきかを示す明確な例とともにすべて解説します。

📚

ランダムな整数

randint(a, b)

a <= N <= b(両端を含む)の範囲でランダムな整数Nを返します。

import random
 
# Random integer between 1 and 10 (inclusive)
print(random.randint(1, 10))  # e.g., 7
 
# Simulate a dice roll
dice = random.randint(1, 6)
print(f"You rolled a {dice}")
 
# Generate random ages for test data
ages = [random.randint(18, 65) for _ in range(5)]
print(ages)  # e.g., [34, 52, 21, 45, 28]

randrange(start, stop, step)

range()と同様ですが、ランダムな要素を返します。stop値は含まれません。

import random
 
# Random even number between 0 and 100
print(random.randrange(0, 101, 2))  # e.g., 42
 
# Random number from 0 to 9
print(random.randrange(10))  # e.g., 7
 
# Random multiple of 5 from 0 to 100
print(random.randrange(0, 101, 5))  # e.g., 35

ランダムな浮動小数点数

random()

[0.0, 1.0)の範囲でランダムな浮動小数点数を返します。

import random
 
print(random.random())  # e.g., 0.7234...
 
# Scale to any range: random float between 10 and 20
value = 10 + random.random() * 10
print(value)  # e.g., 15.23...

uniform(a, b)

a <= N <= bのランダムな浮動小数点数Nを返します。

import random
 
# Random temperature between 98.0 and 99.5
temp = random.uniform(98.0, 99.5)
print(f"Temperature: {temp:.1f}F")  # e.g., Temperature: 98.7F
 
# Random price between 9.99 and 29.99
price = round(random.uniform(9.99, 29.99), 2)
print(f"Price: ${price}")

gauss(mu, sigma) -- 正規分布

import random
 
# Generate normally distributed values (mean=100, std=15)
iq_scores = [round(random.gauss(100, 15)) for _ in range(10)]
print(iq_scores)  # e.g., [112, 95, 103, 88, 107, ...]

ランダムな選択

choice(seq)

空でないシーケンスからランダムに1つの要素を返します。

import random
 
colors = ['red', 'blue', 'green', 'yellow', 'purple']
print(random.choice(colors))  # e.g., 'green'
 
# Random character from a string
print(random.choice('abcdefghij'))  # e.g., 'f'

choices(population, weights, k)

復元抽出(重複可能)でk個の要素のリストを返します。重み付けをサポートします。

import random
 
# Pick 5 random colors (duplicates allowed)
colors = ['red', 'blue', 'green']
print(random.choices(colors, k=5))  # e.g., ['blue', 'red', 'blue', 'green', 'red']
 
# Weighted selection (red is 5x more likely)
weighted = random.choices(
    ['red', 'blue', 'green'],
    weights=[5, 1, 1],
    k=10
)
print(weighted)  # Mostly 'red'

sample(population, k)

非復元抽出(重複なし)でk個のユニークな要素を返します。

import random
 
# Lottery numbers: 6 unique numbers from 1-49
lottery = random.sample(range(1, 50), 6)
print(sorted(lottery))  # e.g., [3, 12, 27, 33, 41, 48]
 
# Random survey sample
employees = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank']
survey_group = random.sample(employees, 3)
print(survey_group)  # e.g., ['Diana', 'Alice', 'Frank']

choice vs choices vs sample

関数復元返り値用途
choice(seq)N/A(単一要素)1要素ランダムに1つ選ぶ
choices(pop, k=n)復元抽出n要素のリスト重み付きランダム、シミュレーション
sample(pop, k=n)非復元抽出n個のユニーク要素のリスト抽選、ランダムな部分集合

シャッフル

shuffle(seq)

リストをインプレースでシャッフルします。Noneを返します。

import random
 
deck = list(range(1, 53))  # 52 cards
random.shuffle(deck)
print(deck[:5])  # e.g., [37, 12, 48, 3, 21]
 
# Deal 5 cards
hand = deck[:5]
remaining = deck[5:]

シードと再現性

シードを設定すると、ランダム出力が再現可能になります -- テストやデバッグに不可欠です。

import random
 
random.seed(42)
print(random.randint(1, 100))  # Always 81
print(random.random())          # Always 0.0744...
 
# Reset seed for same sequence
random.seed(42)
print(random.randint(1, 100))  # 81 again
print(random.random())          # 0.0744... again

シードを使うタイミング

シナリオシード?理由
ユニットテストはい再現可能なテスト結果
デバッグはい正確なバグの再現
シミュレーション(分析)はい再現可能な実験
ゲーム(ゲームプレイ)いいえプレイヤーは真のランダム性を期待
セキュリティ/暗号いいえ(secretsを使用)シードは出力を予測可能にする

テストデータの生成

import random
import string
 
def random_string(length=10):
    """Generate a random alphanumeric string."""
    chars = string.ascii_letters + string.digits
    return ''.join(random.choices(chars, k=length))
 
def random_email():
    """Generate a random email address."""
    name = random_string(8).lower()
    domains = ['gmail.com', 'yahoo.com', 'outlook.com']
    return f"{name}@{random.choice(domains)}"
 
def random_user():
    """Generate a random user record."""
    first_names = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve']
    last_names = ['Smith', 'Jones', 'Brown', 'Wilson', 'Taylor']
    return {
        'name': f"{random.choice(first_names)} {random.choice(last_names)}",
        'email': random_email(),
        'age': random.randint(18, 65),
        'score': round(random.uniform(0, 100), 1),
    }
 
# Generate 5 test users
users = [random_user() for _ in range(5)]
for user in users:
    print(user)

Randomとデータサイエンス

データ分析ワークフローでは、randomモジュールはサンプリング、ブートストラップ、合成データセットの作成に役立ちます。pandasと組み合わせると、テスト用のDataFrameを素早く生成できます:

import random
import pandas as pd
 
random.seed(42)
n = 1000
 
df = pd.DataFrame({
    'age': [random.randint(18, 80) for _ in range(n)],
    'income': [round(random.gauss(50000, 15000), 2) for _ in range(n)],
    'category': random.choices(['A', 'B', 'C'], weights=[5, 3, 2], k=n),
})
print(df.describe())

ランダムデータセットのインタラクティブな探索には、PyGWalker (opens in a new tab)がpandasのDataFrameをJupyter内でTableauスタイルの可視化UIに変換します:

import pygwalker as pyg
walker = pyg.walk(df)

セキュリティ警告:random vs secrets

randomモジュールはセキュリティ目的には適していません。シードが知られている場合、出力は決定的で予測可能です。パスワード、トークン、暗号アプリケーションにはsecretsモジュールを使用してください:

import secrets
 
# Cryptographically secure random token
token = secrets.token_hex(16)
print(token)  # e.g., 'a3f2b8c9d1e4f5a6b7c8d9e0f1a2b3c4'
 
# Secure random integer
secure_int = secrets.randbelow(100)
 
# Secure random choice
secure_choice = secrets.choice(['option1', 'option2', 'option3'])
特徴randomsecrets
アルゴリズムメルセンヌ・ツイスター(PRNG)OSエントロピーソース(CSPRNG)
決定的はい(シード使用時)いいえ
速度高速低速
用途シミュレーション、ゲーム、テストパスワード、トークン、暗号
再現可能はい(seed()使用時)いいえ

FAQ

Pythonでランダムな整数を生成するには?

random.randint(a, b)を使って、aからb(両端を含む)のランダムな整数を取得します。例えば、random.randint(1, 10)は1から10の数を返します。上限を除外する範囲には、random.randrange(start, stop)を使用します。

random.choiceとrandom.sampleの違いは?

random.choice(seq)は1つのランダムな要素を返します。random.sample(population, k)は非復元でk個のユニークな要素を返します。重複を許可して複数の要素を選択するには、random.choices(population, k=n)を使用します。

ランダムな結果を再現可能にするには?

乱数を生成する前にrandom.seed(value)を呼び出します。同じシードを使用すると、毎回同じ乱数列が生成されます。ユニットテストやデバッグに不可欠です。

Pythonのrandomモジュールは安全ですか?

いいえ。randomモジュールはメルセンヌ・ツイスターアルゴリズムを使用しており、決定的で予測可能です。パスワードやトークンなどのセキュリティに敏感なアプリケーションには、暗号学的に安全な乱数ソースを使用するsecretsモジュールを代わりに使用してください。

Pythonでリストをランダムにシャッフルするには?

random.shuffle(my_list)を使って、リストをインプレースでシャッフルします。元のリストが変更され、Noneが返されます。元のリストを変更しないままにする必要がある場合は、先にコピーを作成してください:shuffled = my_list.copy(); random.shuffle(shuffled)

まとめ

Pythonのrandomモジュールは、一般的なランダム化のあらゆるニーズに対応します:整数にはrandint、浮動小数点数にはuniform、シーケンスからの選択にはchoice/choices/sample、並べ替えにはshuffle、再現性にはseed。重要な違いを覚えておきましょう:choicesは重複を許可(復元抽出)、sampleは許可しません(非復元抽出)。そしてセキュリティには決してrandomを使わないでください -- 代わりにsecretsを使用してください。

📚