wake-up-neo.com

Mischen Sie DataFrame-Zeilen

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 Types 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?

215
JNevens

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.

460
Kris

Sie können sklearn dafür einfach verwenden

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

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)

47
joris

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. 

  • funktion gibt keine zurück. Wenn Sie eine Kopie des Originalobjekts behalten möchten, müssen Sie dies tun, bevor Sie an die Funktion gelangen.
  • 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.

Benchmark-Ergebnis

zwischen sklearn.utils.shuffle() und np.random.shuffle() .

ndarray

nd = sklearn.utils.shuffle(nd)

0,10793248389381915 sek. 8x schneller

np.random.shuffle(nd)

0,8897626010002568 sek

DataFrame

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 Sie np.random.shuffle()

verwendeter Code

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)

PythonBenchmarking

23
haku

(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 .

9
NotANumber

AFAIK ist die einfachste Lösung:

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

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

0
PV8

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)

0
soulmachine

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 Typename__s gemischt werden

0
Sundeep Pidugu