Jeg har følgende 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 leses fra en csv-fil. Alle rader som har Type
1 er øverst, etterfulgt av radene med Type
2, etterfulgt av radene med Type
3 osv.
Jeg ønsker å blande rekkefølgen på DataFrames rader, slik at alle Type
ene blir blandet. Et mulig resultat kan være:
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
...
Hvordan kan jeg oppnå dette?
Den idiomatiske måten å gjøre dette på med pandaer er å bruke .sample
-metoden i datarammen, dvs.
df.sample(frac=1)
Nøkkelordargumentet frac
spesifiserer brøkdelen av rader som skal returneres i det tilfeldige utvalget, så frac=1
betyr å returnere alle rader (i tilfeldig rekkefølge).
Merk: Merk:**. Hvis du ønsker å stokke datarammen på stedet og tilbakestille indeksen, kan du f.eks. gjøre følgende
df = df.sample(frac=1).reset_index(drop=True)
Ved å angi drop=True
forhindrer du at .reset_index
oppretter en kolonne som inneholder de gamle indeksoppføringene.
Oppfølgingsmerknad: Selv om det kanskje ikke ser ut som operasjonen ovenfor er in-place, er python/pandas smart nok til ikke å gjøre en annen malloc for det blandede objektet. Det vil si at selv om *referanseobjektet har endret seg (med det mener jeg at id(df_old)
ikke er det samme som id(df_new)
), er det underliggende C-objektet fortsatt det samme. For å vise at dette faktisk er tilfelle, kan du kjøre en enkel minneprofiler:
$ python3 -m memory_profiler .\test.py
Filnavn: .\test.py
Linje # Minnebruk Inkrement Linje Innhold
================================================
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)
Du kan blande radene i en dataramme ved å indeksere med en blandet indeks. Til dette kan du f.eks. bruke np.random.permutation
(men np.random.choice
er også en mulighet):
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
Hvis du vil beholde indeksen nummerert fra 1, 2, .., n som i ditt eksempel, kan du bare tilbakestille indeksen: df_shuffled.reset_index(drop=True)