Ich habe den folgenden 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
...
Der DataFrame wird aus einer CSV-Datei gelesen. Alle Zeilen mit Type
1 befinden sich oben, gefolgt von den Zeilen mit Type
2, gefolgt von den Zeilen mit Type
3 usw.
Ich möchte die Zeilen des DataFrame mischen, so dass alle Type
s gemischt werden. Ein mögliches Ergebnis könnte sein:
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
...
Wie aus dem Ergebnis ersichtlich, wird die Reihenfolge der Zeilen neu gemischt, die Spalten bleiben jedoch gleich. Ich weiß nicht, ob ich das klar erkläre. Sag mir Bescheid, wenn ich es nicht tue.
Wie kann ich das erreichen?
Der idiomatischere Weg, dies mit Pandas zu tun, ist die .sample
-Methode Ihres Datenrahmens, d. H.
df.sample(frac=1)
Das Argument frac
gibt den Bruchteil der Zeilen an, die in der Stichprobe zurückgegeben werden sollen. frac=1
bedeutet, dass alle Zeilen in zufälliger Reihenfolge zurückgegeben werden.
Hinweis: Wenn Sie Ihren Datenrahmen direkt an Ort und Stelle mischen und den Index zurücksetzen möchten, können Sie z.
df = df.sample(frac=1).reset_index(drop=True)
Die Angabe von drop=True
verhindert, dass .reset_index
eine Spalte erstellt, die die alten Indexeinträge enthält.
Sie können sklearn dafür einfach verwenden
from sklearn.utils import shuffle
df = shuffle(df)
Sie können die Zeilen eines Datenrahmens mischen, indem Sie mit einem gemischten Index indizieren. Dazu können Sie zB np.random.permutation
verwenden (aber auch np.random.choice
ist möglich):
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
Wenn Sie den Index wie in Ihrem Beispiel mit 1, 2, .., n nummerieren möchten, können Sie den Index einfach zurücksetzen: df_shuffled.reset_index(drop=True)
TL; DR: np.random.shuffle(ndarray)
kann den Job erledigen.
So in Ihrem Fall
np.random.shuffle(DataFrame.values)
DataFrame
verwendet unter der Haube NumPy ndarray als Datenhalter. (Sie können aus DataFrame-Quellcode prüfen)
Wenn Sie also np.random.shuffle()
verwenden, wird das Array entlang der ersten Achse eines mehrdimensionalen Arrays verschoben. Der Index der Variablen DataFrame
bleibt jedoch nicht gemischt.
Es gibt jedoch einige Punkte, die zu berücksichtigen sind.
sklearn.utils.shuffle()
kann, wie vom Benutzer tj89 vorgeschlagen, random_state
zusammen mit einer anderen Option zur Steuerung der Ausgabe festlegen. Sie können das für Dev-Zwecke wollen.sklearn.utils.shuffle()
ist schneller. WIRD aber die Achseninformationen (Index, Spalte) der Variablen DataFrame
zusammen mit der Variablen ndarray
SHUFFLE.zwischen sklearn.utils.shuffle()
und np.random.shuffle()
.
nd = sklearn.utils.shuffle(nd)
0,10793248389381915 sek. 8x schneller
np.random.shuffle(nd)
0,8897626010002568 sek
df = sklearn.utils.shuffle(df)
0,3183923360193148 sek. 3x schneller
np.random.shuffle(df.values)
0,9357550159329548 sek
Fazit: Wenn die Achseninformationen (Index, Spalte) zusammen mit ndarray gemischt werden sollen, verwenden Sie
sklearn.utils.shuffle()
. Andernfalls verwenden Sienp.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)
(Ich habe nicht genug Reputation, um dies im ersten Beitrag zu kommentieren, daher hoffe ich, dass jemand anderes dies für mich tun kann.) Es gab Bedenken, dass die erste Methode:
df.sample(frac=1)
erstellen Sie eine tiefe Kopie oder ändern Sie einfach den Datenrahmen. Ich habe den folgenden Code ausgeführt:
print(hex(id(df)))
print(hex(id(df.sample(frac=1))))
print(hex(id(df.sample(frac=1).reset_index(drop=True))))
und meine Ergebnisse waren:
0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70
was bedeutet, dass die Methode nicht dasselbe Objekt zurückgibt, wie im letzten Kommentar vorgeschlagen. Also macht diese Methode tatsächlich eine gemischte Kopie .
AFAIK ist die einfachste Lösung:
df_shuffled = df.reindex(np.random.permutation(df.index))
Was auch nützlich ist, wenn Sie es für Machine_learning verwenden und immer die gleichen Daten trennen möchten, können Sie Folgendes verwenden:
df.sample(n=len(df), random_state=42)
dies stellt sicher, dass Sie Ihre zufällige Auswahl immer reproduzierbar halten
mischen Sie den Pandas-Datenrahmen, indem Sie in diesem Fall ein Probenarray nehmen, index , und ordnen Sie seine Reihenfolge zufällig, und legen Sie das Array als Index für den Datenrahmen fest. Sortieren Sie nun den Datenrahmen nach Index. Hier geht Ihr gemischter Datenrahmen
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()
Ausgabe
a b
0 2 6
1 1 5
2 3 7
3 4 8
Fügen Sie Ihren Datenrahmen an der Stelle von mir im obigen Code ein.
Hier ist ein anderer Weg:
df['rnd'] = np.random.Rand(len(df))
df = df.sort_values(by='rnd', inplace=True).drop('rnd', axis=1)
Der einfachste Weg ist der folgende Code. (Python)
from sklearn.utils import shuffle
dataFrame = shuffle(dataFrame)
Dies wird alle Spalten durcheinander bringen und Sie werden eine gute Mischung von allen haben, so dass alle Type
name__s gemischt werden