[pandas] ランダムサンプリング

[pandas] ランダムサンプリング

pandas.DataFrame.sample()

 pandas.DataFrame.sample() メソッドを使うと、データフレームから行や列を 無作為抽出 (ランダムサンプリング) できます。準備として Excel VBA 表計算とプログラミング学習サイト から person.xlsx を読み込んでデータフレームに格納しておきます。person.xlsx には疑似個人情報が 1000 件収められています。

# PDS-1

import numpy as np
import pandas as pd

path = "https://atelierkobato.com/wp-content/uploads/person.xlsx"
data = pd.read_excel(path, header=1)
data

pandas.DataFrame.sample ランダムサンプリング

 上図では 6 行目まで表示して残りは省略しています (1000 件も載せられないので ...)。あまりたくさんの列があると煩わしいので、drop()メソッドで "ふりがな" と "年齢" は削除しておきます。

# PDS-2

data = data.drop(["ふりがな","年齢"], axis=1)
data

pandas.DataFrame.sample 1

 sample()メソッドで 1 行を無作為に抜き出してみましょう (実行結果の列ラベルは省略します)。

# PDS-3

ds = data.sample(random_state=0)
print(ds)
993  栗本 宏樹  男  埼玉県  Twitter

 皆さんと実行結果を一致させるために、randam_state で乱数シードを固定していますが、この引数を削除すると実行ごとに異なる結果となります。第 1 引数 n に整数を渡して複数行を無作為抽出することもできます。

# PDS-4

# dataから無作為に3行を抽出
ds = data.sample(3, random_state=1)
print(ds)
507  根本 汐織  女  大阪府  バトントワリング
818  小西 泰光  男  群馬県 ネイルアート
452  蔵戸 朋美  女  石川県 革細工

 

抽出数を比率で指定する

 frac キーワードで抽出数の比率を指定することもできます。1 を指定すると全体の 100%、0.1 なら 10% を抜粋します。ここでは、0.01 を指定して、全体の 1 %、すなわち 10 件のデータを抜き出してみましょう。

# PDS-5

ds = data.sample(frac=0.01, random_state=2)
print(ds)
37   村崎 笑子    女  山口県  剥製
726  大辻 有沙    女  愛媛県  水上スキー
846  久留島 雅英  男  広島県  応援
295  田崎 ゆい子  女  東京都  パラパラ漫画
924  亀川 愛翔    男  北海道  ペーパークラフト
658  滝井 千佳    女  熊本県  弓道
682  木村 真琴    女  栃木県  物理学
286  木川 理恵    女  福岡県  お菓子作り
880  新屋 草太    男  千葉県  音楽鑑賞
272  隈部 力      男  京都府  ドミノ倒し

 デフォルトでは重複なしで抽出しますが、重複を許可して抽出するときは replace に True を渡してください。また、axis=1 を指定すると列を抽出します。
 

抽出確率を指定する

 data から 5 行だけ抜き出して、新しいデータフレーム data2 に格納しておきます。

# PDS-6

data2 = data.loc[0:4]
data2

pandas.DataFrame.sample 2

 pandas.DataFrame.sample() の weights には、各行が抽出される確率リスト (重み) を渡します。たとえば、data2 から重複を許して最初の行を 60 %, 残りの各行を 10% で抽出するコードは以下のようになります。

# PDS-7

# 各行が抽出される確率
w = [0.6, 0.1, 0.1, 0.1, 0.1]

# 重複を許可して 10 行を抽出
data2.sample(10, random_state=0, replace=True, weights=w)

pandas.DataFrame.sample 3