ランダムサンプリングは、巨大なデータセットからランダムにデータを抽出して解析をおこなう際に用いられる、統計手法の一つだ。

今回はPythonでおこなうランダムサンプリングの例として、トランプのデッキを作る方法を紹介する。

Pythonで52枚のトランプのデッキを用意する

詳しいコードの解説は割愛する。
以下のコードで52枚のトランプが出来上がる。

import pandas as pd

# ハート、スペード、クラブ、ダイヤの頭文字
suits = ['H', 'S', 'C', 'D']

card_val = (list(range(1, 11)) + [10] * 3) * 4

base_names = ['A'] + list(range(2, 11)) + ['J', 'Q', 'K']
# ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']

cards = []

for suit in ['H', 'S', 'C', 'D']:
    cards.extend(str(num) + suit for num in base_names)

deck = pd.Series(card_val, index=cards)
deck[:13]
# AH      1
# 2H      2
# 3H      3
# 4H      4
# 5H      5
# 6H      6
# 7H      7
# 8H      8
# 9H      9
# 10H    10
# JH     10
# QH     10
# KH     10
# dtype: int64

トランプのデッキからカードを引く関数を用意する

次に、用意したデッキからカードを5枚引く関数を用意する。

def draw(deck, n=5):
    return deck.sample(n)

関数が用意できたら、早速実行して結果を見てみよう。

draw(deck)
# 10C    10
# 9D      9
# 8S      8
# QC     10
# 5D      5
# dtype: int64

何度か実行してみると、ランダムにデッキから5枚のカードを抽出できていることが分かるはずだ。

グループ化を応用したランダムサンプリング

さて、次は4つのマークから、それぞれ2枚ずつのカードをランダムサンプリングする例を見ていく。

カード名の最後の文字(H、S、C、D)がマークの頭文字を表しているので、これを利用してグループ化すれば簡単だ。

# カードの最後の文字を取得
get_suit = lambda card: card[-1]

deck.groupby(get_suit).apply(draw, n=2)
# C  QC    10
#    8C     8
# D  8D     8
#    5D     5
# H  4H     4
#    2H     2
# S  9S     9
#    KS    10
# dtype: int64

applyメソッドは、定義したラムダ関数や組み込みの関数を引数に取り、データフレームやシリーズの各行・列に関数を適用することができるメソッドで、これを活用している。