Ik heb het volgende 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
...
Het DataFrame wordt gelezen uit een csv-bestand. Alle rijen met Type
1 staan bovenaan, gevolgd door de rijen met Type
2, gevolgd door de rijen met Type
3, enz.
Ik wil de volgorde van de rijen van het DataFrame door elkaar halen, zodat alle Type
‘s worden gemengd. Een mogelijk resultaat zou kunnen zijn:
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
...
Hoe kan ik dit bereiken?
Antwoord 1, autoriteit 100%
De idiomatische manier om dit met Panda’s te doen, is door de .sample
methode van uw dataframe om alle rijen te samplen zonder vervanging:
df.sample(frac=1)
Het sleutelwoordargument frac
specificeert de fractie rijen die moet worden geretourneerd in de willekeurige steekproef, dus frac=1
betekent dat alle rijen worden geretourneerd (in willekeurige volgorde).
Opmerking:
Als u uw dataframe op zijn plaats wilt shufflen en de index opnieuw wilt instellen, kunt u bijvoorbeeld
df = df.sample(frac=1).reset_index(drop=True)
Hier, door drop=True
op te geven, voorkomt u dat .reset_index
een kolom maakt met de oude indexitems.
Vervolgopmerking:hoewel het er misschien niet uitziet alsof de bovenstaande bewerking in-placeis, is python/panda’s slim genoeg om niet nog een malloc te doen voor de geschudde object. Dat wil zeggen, ook al is het referentieobjectgewijzigd (waarmee ik bedoel dat id(df_old)
niet hetzelfde is als id(df_new)
) , is het onderliggende C-object nog steeds hetzelfde. Om aan te tonen dat dit inderdaad het geval is, kunt u een eenvoudige geheugenprofiler uitvoeren:
$ python3 -m memory_profiler .\test.py
Filename: .\test.py
Line # Mem usage Increment Line Contents
================================================
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)
Antwoord 2, autoriteit 24%
Je kunt hiervoor gewoon sklearn gebruiken
from sklearn.utils import shuffle
df = shuffle(df)
Antwoord 3, autoriteit 6%
U kunt de rijen van een dataframe door elkaar schudden door te indexeren met een geschudde index. Hiervoor kun je bijvoorbeeld np.random.permutation
gebruiken (maar np.random.choice
is ook een mogelijkheid):
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
Als u de index genummerd wilt houden van 1, 2, .., N Zoals in uw voorbeeld, kunt u eenvoudig de index opnieuw instellen: df_shuffled.reset_index(drop=True)
Antwoord 4
(Ik heb niet genoeg reputatie om dit op de bovenste post te becommentariëren, dus ik hoop dat iemand anders dat voor mij kan doen.)Er was een punt van zorg dat de eerste methode:
df.sample(frac=1)
een diepe kopie gemaakt of zojuist het dataframe gewijzigd. Ik heb de volgende code uitgevoerd:
print(hex(id(df)))
print(hex(id(df.sample(frac=1))))
print(hex(id(df.sample(frac=1).reset_index(drop=True))))
en mijn resultaten waren:
0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70
wat betekent dat de methode niethetzelfde object retourneert, zoals werd gesuggereerd in de laatste opmerking. Deze methode maakt dus inderdaad een geschudde kopie.
Antwoord 5
Wat ook handig is, als je het voor Machine_learning gebruikt en altijd dezelfde gegevens wilt scheiden, kun je het volgende gebruiken:
df.sample(n=len(df), random_state=42)
dit zorgt ervoor dat u uw willekeurige keuze altijd reproduceerbaar houdt
Antwoord 6
Het volgende kan een van de manieren zijn:
dataframe = dataframe.sample(frac=1, random_state=42).reset_index(drop=True)
waar
frac=1betekent alle rijen van een dataframe
random_state=42betekent dat je bij elke uitvoering dezelfde volgorde aanhoudt
reset_index(drop=True)betekent het opnieuw initialiseren van de index voor gerandomiseerd dataframe
Antwoord 7
AFAIK de eenvoudigste oplossing is:
df_shuffled = df.reindex(np.random.permutation(df.index))
Antwoord 8
schud het panda’s-dataframe door een voorbeeldarray te nemen, in dit geval index, en de volgorde ervan willekeurig te maken en stel de array vervolgens in als een index van het dataframe. Sorteer nu het dataframe op index. Hier gaat je geschudde dataframe
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()
uitvoer
a b
0 2 6
1 1 5
2 3 7
3 4 8
Voeg je dataframe in op de plaats van mij in bovenstaande code.
Antwoord 9
Hier is een andere manier:
df['rnd'] = np.random.rand(len(df))
df = df.sort_values(by='rnd', inplace=True).drop('rnd', axis=1)