Ho il seguente 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
...
Il DataFrame viene letto da un file csv. Tutte le righe che hanno Tipo
1 sono in cima, seguite dalle righe con Tipo
2, seguite dalle righe con Tipo
3, ecc.
Vorrei mescolare l'ordine delle righe del DataFrame, in modo che tutti i Tipo
siano mescolati. Un possibile risultato potrebbe essere:
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
...
Come posso ottenere questo risultato?
Il modo idiomatico di farlo con pandas è di usare il metodo .sample
del vostro dataframe, cioè
``python
df.sample(frac=1)
L'argomento della parola chiave `frac` specifica la frazione di righe da restituire nel campione casuale, quindi `frac=1` significa restituire tutte le righe (in ordine casuale).
----------
**Nota:**
Se volete mescolare il vostro dataframe in-place e resettare l'indice, potete fare ad es.
```python
df = df.sample(frac=1).reset_index(drop=True)
Qui, specificando drop=True
si impedisce a .reset_index
di creare una colonna contenente le vecchie voci dell'indice.
Nota successiva: Anche se potrebbe non sembrare che l'operazione di cui sopra sia in-place, python/pandas è abbastanza intelligente da non fare un altro malloc per l'oggetto rimescolato. Cioè, anche se l'oggetto di riferimento è cambiato (con questo intendo dire che id(df_old)
non è lo stesso di id(df_new)
), l'oggetto C sottostante è ancora lo stesso. Per mostrare che questo è effettivamente il caso, si potrebbe eseguire un semplice profiler di memoria:
$ python3 -m memory_profiler .\test.py
Nome del file: .\test.py
Linea # Uso della memoria Incremento Contenuto della linea
================================================
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)
Potete mischiare le righe di un dataframe indicizzando con un indice mischiato. Per questo, puoi ad esempio usare np.random.permutation
(ma anche np.random.choice
è una possibilità):
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
Se vuoi mantenere l'indice numerato da 1, 2, .., n come nel tuo esempio, puoi semplicemente resettare l'indice: df_shuffled.reset_index(drop=True)