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, die Type
1 haben, stehen oben, gefolgt von den Zeilen mit Type
2, gefolgt von den Zeilen mit Type
3, usw.
Ich möchte die Reihenfolge der Zeilen des DataFrame's mischen, so dass alle Type
's gemischt sind. 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 kann ich dies erreichen?
Der idiomatische Weg, dies mit Pandas zu tun, ist die Verwendung der Methode .sample
Ihres Datenrahmens, d.h.
df.sample(frac=1)
Das Argument des Schlüsselworts "frac" gibt den Anteil der Zeilen an, die in der Zufallsstichprobe zurückgegeben werden sollen, also bedeutet "frac=1", dass alle Zeilen (in zufälliger Reihenfolge) zurückgegeben werden.
Anmerkung: Wenn Sie Ihren Datenrahmen an Ort und Stelle mischen und den Index zurücksetzen möchten, können Sie z.B. Folgendes tun
df = df.sample(frac=1).reset_index(drop=True)
Hier verhindert die Angabe von drop=True
, dass .reset_index
eine Spalte mit den alten Indexeinträgen erstellt.
Nachtragende Anmerkung: Obwohl es nicht so aussieht, als ob die obige Operation in-place ist, ist Python/Pandas schlau genug, um kein weiteres malloc für das gemischte Objekt durchzuführen. Das heißt, obwohl sich das Referenz-Objekt geändert hat (womit ich meine, dass id(df_old)
nicht dasselbe ist wie id(df_new)
), ist das zugrunde liegende C-Objekt immer noch dasselbe. Um zu zeigen, dass dies tatsächlich der Fall ist, können Sie einen einfachen Speicher-Profiler laufen lassen:
$ python3 -m memory_profiler .\test.py
Dateiname: .\test.py
Zeile # Mem usage Inkrement Zeileninhalt
================================================
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)
Sie können dazu einfach sklearn verwenden
from sklearn.utils import shuffle
df = shuffle(df)
Sie können die Zeilen eines Datenrahmens durch Indizierung mit einem gemischten Index mischen. Dazu kann man z.B. np.random.permutation
verwenden (aber auch np.random.choice
ist eine Möglichkeit):
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 von 1, 2, ..., n nummeriert lassen wollen, können Sie den Index einfach zurücksetzen: df_shuffled.reset_index(drop=True)