J'ai le DataFrame suivant :
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
...
Le DataFrame est lu depuis un fichier csv. Toutes les lignes qui ont le Type
1 sont en haut, suivies des lignes avec le Type
2, suivies des lignes avec le Type
3, etc.
Je voudrais mélanger l'ordre des lignes du DataFrame, afin que tous les Type
's soient mélangés. Un résultat possible serait le suivant :
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
...
Comment puis-je y parvenir ?
La façon idiomatique de faire cela avec pandas est d'utiliser la méthode .sample
de votre dataframe, c'est-à-dire.
``python
df.sample(frac=1)
L'argument du mot-clé `frac` spécifie la fraction de lignes à retourner dans l'échantillon aléatoire, donc `frac=1` signifie retourner toutes les lignes (dans un ordre aléatoire).
----------
**Note:**
Si vous souhaitez mélanger votre cadre de données sur place et réinitialiser l'index, vous pouvez par exemple faire ceci
```python
df = df.sample(frac=1).reset_index(drop=True)
Ici, la spécification de drop=True
empêche .reset_index
de créer une colonne contenant les anciennes entrées d'index.
Note de suivi: Bien qu'il ne semble pas que l'opération ci-dessus soit en-place, python/pandas est assez intelligent pour ne pas faire un autre malloc pour l'objet shufflé. C'est-à-dire que même si l'objet référence a changé (je veux dire par là que id(df_old)
n'est pas le même que id(df_new)
), l'objet C sous-jacent est toujours le même. Pour montrer que c'est bien le cas, vous pouvez lancer un simple profileur de mémoire :
$ python3 -m memory_profiler .\test.py
Nom du fichier : .\test.py
Ligne # Utilisation mémoire Incrémenter Contenu de la ligne
================================================
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)
Vous pouvez mélanger les lignes d'un dataframe en indexant avec un index mélangé. Pour cela, vous pouvez par exemple utiliser np.random.permutation
(mais np.random.choice
est aussi une 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
Si vous voulez garder l'indice numéroté de 1, 2, ..., n comme dans votre exemple, vous pouvez simplement réinitialiser l'indice : df_shuffled.reset_index(drop=True)