Shuffle DataFrame rows

j'ai la base de données suivante:

    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
...

la base de données est lue à partir d'un fichier csv. Toutes les lignes qui ont Type 1 sont en tête, suivis par les lignes avec Type 2, suivie par les lignes avec Type 3, etc.

je voudrais mélanger les lignes de la base de données, de sorte que tous les Type sont 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 le montre le résultat, l'ordre des les lignes sont mélangées, mais les colonnes restent les mêmes. Je ne sais pas si je vais expliquer cela clairement. Prévenez-moi si Je ne le fais pas.

Comment puis-je y parvenir?

165
demandé sur JNevens 2015-04-11 12:47:57

7 réponses

la façon la plus idiomatique de faire cela avec pandas est d'utiliser la méthode .sample de votre dataframe, i.e.

df.sample(frac=1)

l'argument de mot-clé frac spécifie la fraction de lignes à retourner dans l'échantillon aléatoire, donc frac=1 signifie retourner toutes les lignes (dans l'ordre aléatoire).

Note: si vous souhaitez mélanger votre dataframe en place et réinitialiser l'index, vous pouvez faire par exemple

df = df.sample(frac=1).reset_index(drop=True)

ici, en spécifiant drop=True empêche .reset_index de créer une colonne contenant les anciennes entrées de l'index.

348
répondu Kris 2016-01-27 09:18:11

vous pouvez simplement utiliser sklearn pour ce

from sklearn.utils import shuffle
df = shuffle(df)
101
répondu tj89 2016-09-24 07:42:10

vous pouvez mélanger les lignes d'une base de données en indexant avec un index mélangé. Pour cela, vous pouvez par exemple utiliser np.random.permutation (mais np.random.choice est également 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'index numéroté de 1, 2, .. n comme dans votre exemple, vous pouvez simplement réinitialiser l'index: df_shuffled.reset_index(drop=True)

44
répondu joris 2015-04-11 10:26:59

TL;DR : np.random.shuffle(ndarray) peut faire le travail.

Donc, dans votre cas

np.random.shuffle(DataFrame.values)

D'après ce que j'ai compris, DataFrame, sous le capot, utilise NumPy ndarray comme support de données. Vous pouvez vérifier à partir de code source DataFrame . Donc, si vous utilisez np.random.shuffle() , il mélangerait le tableau le long du premier axe d'un tableau multidimensionnel. Mais les colonnes-sage reste le même.

certaines limites sont indiquées ci-après.

  • aucune. Dans le cas où vous souhaitez conserver une copie de l'objet original, vous devez le faire avant de passer à la fonction.
  • sklearn.utils.shuffle() l'utilisateur tj89 suggéré, peut désigner random_state avec une autre option pour contrôler la sortie. Tu peux vouloir ça pour dev purpose.

résultat de référence

entre sklearn.utils.shuffle() et np.random.shuffle() .

ndarray

nd = sklearn.utils.shuffle(nd)

0.10793248389381915 sec. 8x plus rapide

np.random.shuffle(nd)

0.8897626010002568 sec

DataFrame

df = sklearn.utils.shuffle(df)

0.3183923360193148 sec. 3x plus rapide

np.random.shuffle(df.values)', setup=setup, number=1000)

0,9357550159329548 sec

Conclusion: utilisation sklearn.utils.shuffle() , si possible.

code utilisé

setup = '''
import numpy as np
import pandas as pd
from sklearn.utils import shuffle
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)

13
répondu haku 2018-03-23 06:07:48

(Je n'ai pas assez de réputation pour commenter ceci sur le post supérieur, donc j'espère que quelqu'un d'autre peut faire cela pour moi.) on s'est inquiété du fait que la première méthode:

df.sample(frac=1)

fait une copie profonde ou vient de changer la base de données. J'ai lancé 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 étaient:

0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70

qui signifie que la méthode est et non retournant le même objet, comme il était suggéré dans le dernier commentaire. Ainsi, cette méthode fait en effet une copie mélangée 1519130920".

3
répondu NotANumber 2018-07-11 16:31:32

AFAIK la solution la plus simple est:

df_shuffled = df.reindex(np.random.permutation(df.index))
1
répondu Ido Cohn 2018-06-27 13:09:13

mélanger la base de données pandas en prenant un tableau échantillon dans ce cas index et randomiser son ordre puis définir le tableau comme un indice de la base de données. Maintenant, triez la base de données selon l'indice.

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 base de données à la place de la mienne dans le code ci-dessus .

0
répondu Abhilash Reddy Yammanuru 2018-06-13 11:28:40