以下の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ファイルから読み込まれます。 Type
1を持つすべての行が一番上にあり、続いてType
2を持つ行、さらにType
3を持つ行などが続きます。
すべてのType
が混在するように、DataFrameの行の順序を入れ替えます。考えられる結果は次のとおりです。
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
...
どうすればこれを達成できますか?
パンダでこれを行うためのもっと慣用的な方法は、データフレームの.sample
メソッドを使うことです。
df.sample(frac=1)
frac
キーワード引数は、ランダムサンプルで返す行の小数部を指定するため、frac=1
はすべての行を(ランダムな順序で)返すことを意味します。
注: データフレームをその場でシャッフルしてインデックスをリセットしたい場合は、次のようにします。
df = df.sample(frac=1).reset_index(drop=True)
ここで、drop=True
を指定すると、.reset_index
は古いインデックスエントリを含む列を作成できなくなります。
あなたは単にこれのためにsklearnを使うことができます
from sklearn.utils import shuffle
df = shuffle(df)
シャッフルインデックスを使ってインデックスを付けることで、データフレームの行をシャッフルすることができます。これには、たとえばnp.random.permutation
を使用できます(ただし、np.random.choice
も可能です)。
In [12]: df = pd.read_csv(StringIO(s), sep="\s+")
In [13]: df
Out[13]:
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
In [14]: df.iloc[np.random.permutation(len(df))]
Out[14]:
Col1 Col2 Col3 Type
46 16 17 18 3
45 13 14 15 3
20 7 8 9 2
0 1 2 3 1
1 4 5 6 1
21 10 11 12 2
例のように1、2、..、nの番号を付けたままにしたい場合は、単にインデックスをリセットします。df_shuffled.reset_index(drop=True)
TL; DR :np.random.shuffle(ndarray)
は仕事をすることができます。
だから、あなたの場合は
np.random.shuffle(DataFrame.values)
DataFrame
は、フードの下で、データホルダーとしてNumPy ndarrayを使用します。 ( DataFrameソースコード から確認できます。)
したがって、 np.random.shuffle()
を使用すると、多次元配列の最初の軸に沿って配列がシャッフルされます。しかしDataFrame
のインデックスはシャッフルされていないままです。
しかし、考慮すべき点がいくつかあります。
sklearn.utils.shuffle()
、ユーザーtj89が示唆しているように、出力を制御するための別のオプションと共にrandom_state
を指定することができます。あなたは開発目的のためにそれが欲しいかもしれません。sklearn.utils.shuffle()
は速いです。しかしDataFrame
の軸情報(index、column)とそれに含まれるndarray
はシャフリングします。sklearn.utils.shuffle()
と np.random.shuffle()
の間。
nd = sklearn.utils.shuffle(nd)
0.10793248389381915秒。 8倍速い
np.random.shuffle(nd)
0.8897626010002568秒
df = sklearn.utils.shuffle(df)
0.3183923360193148秒。 3倍速い
np.random.shuffle(df.values)
0.9357550159329548秒
結論:軸情報(index、column)をndarrayと一緒にシャッフルしても問題ない場合は、
sklearn.utils.shuffle()
を使用してください。それ以外の場合は、np.random.shuffle()
を使用します。
import timeit
setup = '''
import numpy as np
import pandas as pd
import sklearn
nd = np.random.random((1000, 100))
df = pd.DataFrame(nd)
'''
timeit.timeit('nd = sklearn.utils.shuffle(nd)', setup=setup, number=1000)
timeit.timeit('np.random.shuffle(nd)', setup=setup, number=1000)
timeit.timeit('df = sklearn.utils.shuffle(df)', setup=setup, number=1000)
timeit.timeit('np.random.shuffle(df.values)', setup=setup, number=1000)
(私はこれをトップの投稿にコメントするのに十分な評判を持っていないので、他の誰かが私のためにそれをできることを願っています。) 最初の方法に懸念が生じました
df.sample(frac=1)
ディープコピーを作成するか、データフレームを変更しただけです。私は次のコードを実行しました:
print(hex(id(df)))
print(hex(id(df.sample(frac=1))))
print(hex(id(df.sample(frac=1).reset_index(drop=True))))
そして私の結果は次のとおりです。
0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70
これは、最後のコメントで提案したように、メソッドが同じオブジェクトを返すnotであることを意味します。それで、このメソッドは確かにシャッフルコピーを作ります。
最も簡単な解決策は、次のとおりです。
df_shuffled = df.reindex(np.random.permutation(df.index))
また、Machine_learningに使用し、常に同じデータを分離したい場合は、次のように使用できます。
df.sample(n=len(df), random_state=42)
これにより、ランダムな選択を常に複製可能に保つことができます
この場合はサンプル配列 index を取ってパンダデータフレームをシャッフルし、その順序をランダム化してから配列をデータフレームのインデックスとして設定します。次にインデックスに従ってデータフレームをソートします。これがシャッフルされたデータフレームです
import random
df = pd.DataFrame({"a":[1,2,3,4],"b":[5,6,7,8]})
index = [i for i in range(df.shape[0])]
random.shuffle(index)
df.set_index([index]).sort_index()
出力
a b
0 2 6
1 1 5
2 3 7
3 4 8
上記のコードであなたのデータフレームを私の代わりに挿入してください。
これは別の方法です:
df['rnd'] = np.random.Rand(len(df)) df = df.sort_values(by='rnd', inplace=True).drop('rnd', axis=1)
最も簡単な方法は以下のコードです。 (Python)
from sklearn.utils import shuffle
dataFrame = shuffle(dataFrame)
これですべての列が混乱し、すべてのType
が混在するように、すべてがうまく組み合わされます。