次の DataFrame があります。
Col1 Col2 Col3 Type
0 1 2 3 1
1 4 5 6 1
...
20 7 8 9 2
21 10 11 12 2
...
45 13 14 15 3
46 16 17 18 3
...
DataFrame は CSV ファイルから読み取られます。1 の行がすべてType
一番上に表示され、次にType
2 の行、次に 3 の行Type
、というように続きます。
DataFrame の行の順序をシャッフルして、すべてType
が混在するようにしたいと思います。考えられる結果は次のようになります。
Col1 Col2 Col3 Type
0 7 8 9 2
1 13 14 15 3
...
20 1 2 3 1
21 10 11 12 2
...
45 4 5 6 1
46 16 17 18 3
...
どうすればこれを実現できるでしょうか?
ベストアンサー1
Pandasでこれを行う慣用的な方法は、.sample
データフレームのすべての行を置換せずにサンプリングするメソッド:
df.sample(frac=1)
キーワードfrac
引数は、ランダム サンプルで返される行の割合を指定します。つまり、frac=1
すべての行を (ランダムな順序で) 返すことを意味します。
注:データフレームをその場でシャッフルしてインデックスをリセットしたい場合は、次のようにします。
df = df.sample(frac=1).reset_index(drop=True)
ここで指定すると、古いインデックス エントリを含む列が作成drop=True
されなくなります。.reset_index
補足:上記の操作がインプレースで実行されているようには見えないかもしれませんが、python/pandas はシャッフルされたオブジェクトに対して別の malloc を実行しないほど賢いです。つまり、参照オブジェクトが変更されたとしても (つまり、 はid(df_old)
同じではないid(df_new)
)、基礎となる C オブジェクトは同じままです。これが実際に当てはまることを示すには、単純なメモリ プロファイラーを実行します。
$ python3 -m memory_profiler .\test.py
Filename: .\test.py
Line # Mem usage Increment Line Contents
================================================
5 68.5 MiB 68.5 MiB @profile
6 def shuffle():
7 847.8 MiB 779.3 MiB df = pd.DataFrame(np.random.randn(100, 1000000))
8 847.9 MiB 0.1 MiB df = df.sample(frac=1).reset_index(drop=True)