web-dev-qa-db-ja.com

DataFrame行をシャッフルする

以下の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
...

どうすればこれを達成できますか?

260
JNevens

パンダでこれを行うためのもっと慣用的な方法は、データフレームの.sampleメソッドを使うことです。

df.sample(frac=1)

fracキーワード引数は、ランダムサンプルで返す行の小数部を指定するため、frac=1はすべての行を(ランダムな順序で)返すことを意味します。

注: データフレームをその場でシャッフルしてインデックスをリセットしたい場合は、次のようにします。

df = df.sample(frac=1).reset_index(drop=True)

ここで、drop=Trueを指定すると、.reset_indexは古いインデックスエントリを含む列を作成できなくなります。

521
Kris

あなたは単にこれのためにsklearnを使うことができます

from sklearn.utils import shuffle
df = shuffle(df)
143
tj89

シャッフルインデックスを使ってインデックスを付けることで、データフレームの行をシャッフルすることができます。これには、たとえば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)

47
joris

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() の間。

ndarray

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)

pythonベンチマーク

28
haku

(私はこれをトップの投稿にコメントするのに十分な評判を持っていないので、他の誰かが私のためにそれをできることを願っています。) 最初の方法に懸念が生じました

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であることを意味します。それで、このメソッドは確かにシャッフルコピーを作ります。

10
NotANumber

最も簡単な解決策は、次のとおりです。

df_shuffled = df.reindex(np.random.permutation(df.index))
3
Ido Cohn

また、Machine_learningに使用し、常に同じデータを分離したい場合は、次のように使用できます。

df.sample(n=len(df), random_state=42)

これにより、ランダムな選択を常に複製可能に保つことができます

0
PV8

この場合はサンプル配列 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)

0
soulmachine

最も簡単な方法は以下のコードです。 (Python)

from sklearn.utils import shuffle
dataFrame = shuffle(dataFrame)

これですべての列が混乱し、すべてのTypeが混在するように、すべてがうまく組み合わされます。

0
Sundeep Pidugu