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 à partir d'un fichier csv. Toutes les lignes qui ont Type
1 sont en haut, suivies des lignes avec Type
2, suivies des lignes avec Type
3, etc.
Je voudrais mélanger les lignes du DataFrame, de sorte que tous les Type
soient mélangés. Un résultat possible pourrait être:
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
...
Comme on peut le voir d'après le résultat, l'ordre des lignes est mélangé, mais les colonnes restent les mêmes. Je ne sais pas si j'explique cela clairement. Faites-moi savoir si je ne le fais pas.
Comment puis-je atteindre cet objectif?
La façon la plus idiomatique de le faire avec des pandas est d’utiliser la méthode .sample
de votre dataframe, c’est-à-dire.
df.sample(frac=1)
L'argument frac
indique la fraction de lignes à renvoyer dans l'échantillon aléatoire. frac=1
signifie donc renvoyer toutes les lignes (dans un ordre aléatoire).
Remarque: Si vous souhaitez mélanger votre dataframe sur place et réinitialiser l'index, vous pouvez le faire, par exemple.
df = df.sample(frac=1).reset_index(drop=True)
Ici, spécifier drop=True
empêche .reset_index
de créer une colonne contenant les anciennes entrées d'index.
Vous pouvez simplement utiliser sklearn pour cela
from sklearn.utils import shuffle
df = shuffle(df)
Vous pouvez mélanger les lignes d'une image 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 souhaitez conserver l'index numéroté de 1, 2, .., n comme dans votre exemple, vous pouvez simplement réinitialiser l'index: df_shuffled.reset_index(drop=True)
TL; DR: np.random.shuffle(ndarray)
peut faire le travail.
Donc, dans votre cas
np.random.shuffle(DataFrame.values)
DataFrame
, sous le capot, utilise NumPy ndarray en tant que détenteur de données. (Vous pouvez vérifier depuis le code source de DataFrame )
Donc, si vous utilisez np.random.shuffle()
, le tableau sera mélangé le long du premier axe d'un tableau multidimensionnel. Mais l'index de la DataFrame
reste non brassé.
Cependant, il y a quelques points à considérer.
sklearn.utils.shuffle()
, comme l’a suggéré l’utilisateur tj89, peut désigner random_state
avec une autre option permettant de contrôler la sortie. Vous voudrez peut-être cela à des fins de développement.sklearn.utils.shuffle()
est plus rapide. Mais va effacer les informations d'axe (index, colonne) de la DataFrame
avec la ndarray
qu'il contient.entre sklearn.utils.shuffle()
et np.random.shuffle()
.
nd = sklearn.utils.shuffle(nd)
0,10793248389381915 sec. 8x plus rapide
np.random.shuffle(nd)
0.8897626010002568 sec
df = sklearn.utils.shuffle(df)
0.3183923360193148 sec. 3x plus rapide
np.random.shuffle(df.values)
0.9357550159329548 sec
Conclusion: Si les informations sur l’axe (index, colonne) doivent être mélangées avec ndarray, utilisez
sklearn.utils.shuffle()
. Sinon, utiliseznp.random.shuffle()
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)
((Je n'ai pas assez de réputation pour commenter cela sur le post le plus haut, j'espère que quelqu'un d'autre pourra le faire pour moi.)} Il y avait un problème qui était soulevé concernant la première méthode:
df.sample(frac=1)
fait une copie profonde ou vient de changer le dataframe. J'ai couru le code suivant:
print(hex(id(df)))
print(hex(id(df.sample(frac=1))))
print(hex(id(df.sample(frac=1).reset_index(drop=True))))
et mes résultats ont été:
0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70
ce qui signifie que la méthode est pas renvoyer le même objet, comme suggéré dans le dernier commentaire. Donc, cette méthode crée effectivement un mélange copie.
Autant que je sache, la solution la plus simple est:
df_shuffled = df.reindex(np.random.permutation(df.index))
Ce qui est également utile, si vous l'utilisez pour Machine_learning et souhaitez séparer toujours les mêmes données, vous pouvez utiliser:
df.sample(n=len(df), random_state=42)
cela garantit que vous gardez votre choix aléatoire toujours réplicable
mélangez le bloc de données pandas en prenant un exemple de tableau dans ce cas index et aléatoirement son ordre, puis définissez le tableau comme un index du cadre de données. Maintenant, triez le bloc de données en fonction de l'index. Voici votre dataframe mélangé
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()
sortie
a b
0 2 6
1 1 5
2 3 7
3 4 8
Insérez votre cadre de données à la place du mien dans le code ci-dessus.
Voici un autre moyen:
df['rnd'] = np.random.Rand(len(df))
df = df.sort_values(by='rnd', inplace=True).drop('rnd', axis=1)
La façon la plus simple de faire est le code ci-dessous. (Python)
from sklearn.utils import shuffle
dataFrame = shuffle(dataFrame)
Cela va bouger toutes les colonnes et vous aurez un bon mélange de toutes, de sorte que tous les Type
'soient mélangés