pandasの行・列をランダムサンプリング(抽出)するsample

Modified: | Tags: Python, pandas

pandas.DataFrame, Seriessample()メソッドで、行・列または要素をランダムに抽出(ランダムサンプリング)できる。大きいサイズのpandas.DataFrame, Seriesのデータを確認するときに便利。

ここでは以下の内容について説明する。

  • 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.Seriessample()も引数などの使い方は同じ。

なお、大きいサイズの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

引数axis1とすると行ではなく列がランダムに抽出される。

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

nfracを同時に指定するとエラー。

# 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

引数replaceTrueとすると、抽出される行・列の重複が許可される。デフォルトは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に元の行数・列数より大きいサンプリング数を指定したり、引数frac1より大きい値を指定したりできる。

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_indexTrueにする。

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

関連カテゴリー

関連記事