pandasの行・列をランダムサンプリング(抽出)するsample
pandas.DataFrame, Seriesのsample()メソッドで、行・列または要素をランダムに抽出(ランダムサンプリング)できる。大きいサイズのpandas.DataFrame, Seriesのデータを確認するときに便利。
- pandas.DataFrame.sample — pandas 1.4.2 documentation
- pandas.Series.sample — pandas 1.4.2 documentation
ここでは以下の内容について説明する。
sample()のデフォルト動作- 行・列を指定: 引数
axis - 抽出する行数・列数を指定: 引数
n - 抽出する行・列の割合を指定: 引数
frac - 乱数シードを固定: 引数
random_state - 重複を許可: 引数
replace - インデックス(行番号)の振り直し: 引数
ignore_index,reset_index()
例としてseabornにサンプルとして含まれているirisデータセットを使う。
import pandas as pd
import seaborn as sns
df = sns.load_dataset("iris")
print(df.shape)
# (150, 5)
例はpandas.DataFrameだが、pandas.Seriesのsample()も引数などの使い方は同じ。
なお、大きいサイズのpandas.DataFrame, Seriesのデータを確認するときに使えるほかのメソッドとして、先頭・末尾の行を返すhead()とtail()もある。
sample()のデフォルト動作
引数を何も指定しないと、ランダムで1行が返される。
print(df.sample())
# sepal_length sepal_width petal_length petal_width species
# 133 6.3 2.8 5.1 1.5 virginica
行・列を指定: 引数axis
引数axisを1とすると行ではなく列がランダムに抽出される。
print(df.sample(axis=1))
# petal_width
# 0 0.2
# 1 0.2
# 2 0.2
# 3 0.2
# 4 0.2
# .. ...
# 145 2.3
# 146 1.9
# 147 2.0
# 148 2.3
# 149 1.8
#
# [150 rows x 1 columns]
抽出する行数・列数を指定: 引数n
引数nで抽出する行数・列数を指定できる。
print(df.sample(n=3))
# sepal_length sepal_width petal_length petal_width species
# 29 4.7 3.2 1.6 0.2 setosa
# 67 5.8 2.7 4.1 1.0 versicolor
# 18 5.7 3.8 1.7 0.3 setosa
抽出する行・列の割合を指定: 引数frac
引数fracで抽出する行・列の割合を指定できる。1だと100%。
print(df.sample(frac=0.04))
# sepal_length sepal_width petal_length petal_width species
# 15 5.7 4.4 1.5 0.4 setosa
# 66 5.6 3.0 4.5 1.5 versicolor
# 131 7.9 3.8 6.4 2.0 virginica
# 64 5.6 2.9 3.6 1.3 versicolor
# 81 5.5 2.4 3.7 1.0 versicolor
# 137 6.4 3.1 5.5 1.8 virginica
nとfracを同時に指定するとエラー。
# print(df.sample(n=3, frac=0.04))
# ValueError: Please enter a value for `frac` OR `n`, not both
乱数シードを固定: 引数random_state
引数random_stateで乱数シードを指定して乱数生成器を初期化できる。同じ値を指定すると常に同じように行・列が返される。
print(df.sample(n=3, random_state=0))
# sepal_length sepal_width petal_length petal_width species
# 114 5.8 2.8 5.1 2.4 virginica
# 62 6.0 2.2 4.0 1.0 versicolor
# 33 5.5 4.2 1.4 0.2 setosa
print(df.sample(n=3, random_state=0))
# sepal_length sepal_width petal_length petal_width species
# 114 5.8 2.8 5.1 2.4 virginica
# 62 6.0 2.2 4.0 1.0 versicolor
# 33 5.5 4.2 1.4 0.2 setosa
重複を許可: 引数replace
引数replaceをTrueとすると、抽出される行・列の重複が許可される。デフォルトはFalse。
print(df.head(3))
# sepal_length sepal_width petal_length petal_width species
# 0 5.1 3.5 1.4 0.2 setosa
# 1 4.9 3.0 1.4 0.2 setosa
# 2 4.7 3.2 1.3 0.2 setosa
print(df.head(3).sample(n=3, replace=True))
# sepal_length sepal_width petal_length petal_width species
# 0 5.1 3.5 1.4 0.2 setosa
# 0 5.1 3.5 1.4 0.2 setosa
# 2 4.7 3.2 1.3 0.2 setosa
replace=Trueの場合、引数nに元の行数・列数より大きいサンプリング数を指定したり、引数fracに1より大きい値を指定したりできる。
print(df.head(3).sample(n=5, replace=True))
# sepal_length sepal_width petal_length petal_width species
# 1 4.9 3.0 1.4 0.2 setosa
# 2 4.7 3.2 1.3 0.2 setosa
# 0 5.1 3.5 1.4 0.2 setosa
# 0 5.1 3.5 1.4 0.2 setosa
# 1 4.9 3.0 1.4 0.2 setosa
print(df.head(3).sample(frac=2, replace=True))
# sepal_length sepal_width petal_length petal_width species
# 2 4.7 3.2 1.3 0.2 setosa
# 1 4.9 3.0 1.4 0.2 setosa
# 2 4.7 3.2 1.3 0.2 setosa
# 2 4.7 3.2 1.3 0.2 setosa
# 0 5.1 3.5 1.4 0.2 setosa
# 2 4.7 3.2 1.3 0.2 setosa
インデックス(行番号)の振り直し: 引数ignore_index, reset_index()
結果のインデックス(行番号)を0始まりに振り直したい場合は、引数ignore_indexをTrueにする。
print(df.sample(n=3, ignore_index=True))
# sepal_length sepal_width petal_length petal_width species
# 0 5.2 2.7 3.9 1.4 versicolor
# 1 6.3 2.5 4.9 1.5 versicolor
# 2 5.7 3.0 4.2 1.2 versicolor
ignore_indexはpandas1.3.0で追加された。それより前のバージョンではreset_index()メソッドを使えばよい。元のインデックスを削除するために引数drop=Trueとする。
print(df.sample(n=3).reset_index(drop=True))
# sepal_length sepal_width petal_length petal_width species
# 0 4.9 3.1 1.5 0.2 setosa
# 1 7.9 3.8 6.4 2.0 virginica
# 2 6.3 2.8 5.1 1.5 virginica