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 l'ordre des lignes du DataFrame, afin que tous 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
...
Comment puis-je atteindre cet objectif?
.copy()
vous faites toujours référence au même objet sous-jacent.Vous pouvez simplement utiliser sklearn pour cela
la source
Vous pouvez mélanger les lignes d'une trame de données en l'indexant avec un index mélangé. Pour cela, vous pouvez par exemple utiliser
np.random.permutation
(maisnp.random.choice
c'est aussi une possibilité):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)
la source
TL; DR :
np.random.shuffle(ndarray)
peut faire le travail.Donc, dans ton cas
DataFrame
, sous le capot, utilise NumPy ndarray comme support de données. (Vous pouvez vérifier à partir du code source DataFrame )Donc, si vous utilisez
np.random.shuffle()
, cela mélange le tableau le long du premier axe d'un tableau multidimensionnel. Mais l'indice desDataFrame
restes n'a pas été mélangé.Cependant, il y a quelques points à considérer.
sklearn.utils.shuffle()
, comme l'a suggéré l'utilisateur tj89, peut désignerrandom_state
une autre option pour contrôler la sortie. Vous voudrez peut-être cela à des fins de développement.sklearn.utils.shuffle()
est plus rapide. Mais SHUFFLE les informations d'axe (index, colonne) duDataFrame
avec lendarray
contenu.Résultat de référence
entre
sklearn.utils.shuffle()
etnp.random.shuffle()
.ndarray
0,10793248389381915 sec. 8x plus rapide
0.8897626010002568 sec
Trame de données
0.3183923360193148 sec. 3x plus rapide
0.9357550159329548 sec
code utilisé
pythonanalyse comparative
la source
df = df.sample(frac=1)
exactement la même chose quedf = sklearn.utils.shuffle(df)
? Selon mes mesuresdf = df.sample(frac=1)
est plus rapide et semble effectuer exactement la même action. Ils allouent également tous deux une nouvelle mémoire.np.random.shuffle(df.values)
est la plus lente, mais n'alloue pas de nouvelle mémoire.df.sample(frac=1)
c'est environ 20% plus rapide quesklearn.utils.shuffle(df)
, en utilisant le même code ci-dessus. Ou vous pourriez fairesklearn.utils.shuffle(ndarray)
pour obtenir un résultat différent.(Je n'ai pas assez de réputation pour commenter cela sur le premier post, donc j'espère que quelqu'un d'autre pourra le faire pour moi.) Il y avait une préoccupation soulevée que la première méthode:
fait une copie complète ou juste changé le dataframe. J'ai exécuté le code suivant:
et mes résultats étaient:
ce qui signifie que la méthode ne renvoie pas le même objet, comme cela a été suggéré dans le dernier commentaire. Cette méthode fait donc une copie mélangée .
la source
id
), l'objet sous-jacent n'est pas copié. En d'autres termes, l'opération est effectivement en mémoire (bien qu'il ne soit certes pas évident).Ce qui est également utile, si vous l'utilisez pour Machine_learning et souhaitez toujours séparer les mêmes données, vous pouvez utiliser:
cela garantit que vous gardez votre choix aléatoire toujours reproductible
la source
AFAIK la solution la plus simple est:
la source
np.random.permutation
: "... Si x est un tableau, faites une copie et mélangez les éléments de manière aléatoire". Documentation deDataFrame.reindex
: "Un nouvel objet est produit sauf si le nouvel index est équivalent à celui en cours et copie = False". La réponse est donc parfaitement sûre (bien qu'elle produise une copie).np.random.permutation says
, et selon les versions de numpy, vous obtenez l'effet que j'ai décrit ou celui que vous mentionnez. Avec numpy> 1.15.0, créant un dataframe et faisant un plainnp.random.permutation(df.index)
, les indices dans le df d'origine changent. La même chose n'est pas vraie pour numpy == 1.14.6. Donc, plus que jamais, je répète mon avertissement: cette façon de faire est dangereuse en raison d'effets secondaires imprévus et de dépendances de version.Index
type ... En tout cas, je base mes recommandations / avertissements sur le comportement réel, pas sur les documents: pmélanger la trame de données pandas en prenant un échantillon de tableau dans ce cas index et randomiser son ordre puis définir le tableau comme un index de trame de données. Triez maintenant le bloc de données en fonction de l'index. Voilà votre cadre de données mélangé
production
Insérez votre bloc de données à la place du mien dans le code ci-dessus.
la source
Voici une autre façon:
df['rnd'] = np.random.rand(len(df)) df = df.sort_values(by='rnd', inplace=True).drop('rnd', axis=1)
la source