pandas.DataFrame, Seriesの行をシャッフル

Modified: | Tags: Python, pandas

pandas.DataFrameの行、pandas.Seriesの要素をランダムに並び替える(シャッフルする)にはsample()メソッドを使う。他の方法もあるが、sample()メソッドを使う方法は他のモジュールをインポートしたりする必要がないので便利。

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

  • sample()に引数frac=1を指定
  • インデックス(行番号)の振り直し: 引数ignore_index, reset_index()
  • 元のオブジェクトを更新

例として以下のデータを使用する。

import pandas as pd

df = pd.read_csv('data/src/sample_pandas_normal.csv')
print(df)
#       name  age state  point
# 0    Alice   24    NY     64
# 1      Bob   42    CA     92
# 2  Charlie   18    CA     70
# 3     Dave   68    TX     70
# 4    Ellen   24    CA     88
# 5    Frank   30    NY     57

例はpandas.DataFrameだが、pandas.Seriesでも同様のやり方でシャッフルできる。

なお、順番がバラバラの行をインデックスや列の値に従ってソートするにはsort_values(), sort_index()を使う。以下の記事を参照。

sample()に引数frac=1を指定

sample()メソッドの詳細は以下の記事を参照。

引数frac=1とすると、すべての行数分のランダムサンプリングをすることになり、全体をランダムに並び替える(シャッフルする)ことに等しい。

print(df.sample(frac=1))
#       name  age state  point
# 2  Charlie   18    CA     70
# 1      Bob   42    CA     92
# 3     Dave   68    TX     70
# 0    Alice   24    NY     64
# 5    Frank   30    NY     57
# 4    Ellen   24    CA     88

引数random_stateを指定すると乱数シードを固定して乱数生成器を初期化できる。同じ値を指定すると常に同じように並び替えられる。

print(df.sample(frac=1, random_state=0))
#       name  age state  point
# 5    Frank   30    NY     57
# 2  Charlie   18    CA     70
# 1      Bob   42    CA     92
# 3     Dave   68    TX     70
# 0    Alice   24    NY     64
# 4    Ellen   24    CA     88

print(df.sample(frac=1, random_state=0))
#       name  age state  point
# 5    Frank   30    NY     57
# 2  Charlie   18    CA     70
# 1      Bob   42    CA     92
# 3     Dave   68    TX     70
# 0    Alice   24    NY     64
# 4    Ellen   24    CA     88

インデックス(行番号)の振り直し: 引数ignore_index, reset_index()

結果のインデックス(行番号)を0始まりに振り直したい場合は、sample()の引数ignore_indexTrueにする。

print(df.sample(frac=1, ignore_index=True))
#       name  age state  point
# 0    Ellen   24    CA     88
# 1    Frank   30    NY     57
# 2      Bob   42    CA     92
# 3     Dave   68    TX     70
# 4    Alice   24    NY     64
# 5  Charlie   18    CA     70

ignore_indexはpandas1.3.0で追加された。それより前のバージョンではreset_index()メソッドを使えばよい。元のインデックスを削除するために引数drop=Trueとする。

print(df.sample(frac=1).reset_index(drop=True))
#       name  age state  point
# 0      Bob   42    CA     92
# 1     Dave   68    TX     70
# 2    Alice   24    NY     64
# 3  Charlie   18    CA     70
# 4    Frank   30    NY     57
# 5    Ellen   24    CA     88

元のオブジェクトを更新

元のオブジェクトを更新したい場合は元のオブジェクトに代入して上書きする。

df = df.sample(frac=1)
print(df)
#       name  age state  point
# 0    Alice   24    NY     64
# 5    Frank   30    NY     57
# 1      Bob   42    CA     92
# 4    Ellen   24    CA     88
# 3     Dave   68    TX     70
# 2  Charlie   18    CA     70

関連カテゴリー

関連記事