Mezclar filas del marco de datos

Resuelto JNevens asked hace 9 años • 15 respuestas

Tengo el siguiente marco de datos:

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

El DataFrame se lee desde un archivo CSV. Todas las filas que tienen Type1 están en la parte superior, seguidas por las filas con Type2, seguidas por las filas conType 3, etc.

Me gustaría mezclar el orden de las filas del DataFrame para que todas Typeestén mezcladas. Un posible resultado podría ser:

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

¿Cómo puedo conseguir esto?

JNevens avatar Apr 11 '15 16:04 JNevens
Aceptado

La forma idiomática de hacer esto con Pandas es usar el .samplemétodo de su marco de datos para muestrear todas las filas sin reemplazo:

df.sample(frac=1)

El fracargumento de la palabra clave especifica la fracción de filas que se devolverán en la muestra aleatoria, por lo que frac=1significa devolver todas las filas (en orden aleatorio).


Nota: Si desea mezclar su marco de datos en el lugar y restablecer el índice, puede hacerlo, por ejemplo

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

Aquí, especificar drop=Trueimpide .reset_indexcrear una columna que contenga las entradas de índice antiguas.

Nota de seguimiento: aunque puede que no parezca que la operación anterior está implementada , python/pandas es lo suficientemente inteligente como para no realizar otro malloc para el objeto barajado. Es decir, aunque el objeto de referencia haya cambiado (con lo que quiero decir que id(df_old)no es el mismo que id(df_new)), el objeto C subyacente sigue siendo el mismo. Para demostrar que este es realmente el caso, puede ejecutar un generador de perfiles de memoria simple:

$ python3 -m memory_profiler .\test.py
Filename: .\test.py

Line #    Mem usage    Increment   Line Contents
================================================
     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)

Kris avatar Jan 19 '2016 14:01 Kris

Simplemente puedes usar sklearnpara esto

from sklearn.utils import shuffle
df = shuffle(df)
tj89 avatar Sep 24 '2016 07:09 tj89

Puede mezclar las filas de un marco de datos indexando con un índice aleatorio. Para ello, puede utilizar, por ejemplo np.random.permutation(pero np.random.choicetambién es una posibilidad):

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 desea mantener el índice numerado de 1, 2, .., n como en su ejemplo, simplemente puede restablecer el índice:df_shuffled.reset_index(drop=True)

joris avatar Apr 11 '2015 10:04 joris

(No tengo suficiente reputación para comentar esto en la publicación principal, así que espero que alguien más pueda hacerlo por mí). Se planteó la preocupación de que el primer método:

df.sample(frac=1)

Hace una copia profunda o simplemente cambia el marco de datos. Ejecuté el siguiente código:

print(hex(id(df)))
print(hex(id(df.sample(frac=1))))
print(hex(id(df.sample(frac=1).reset_index(drop=True))))

y mis resultados fueron:

0x1f8a784d400
0x1f8b9d65e10
0x1f8b9d65b70

lo que significa que el método no devuelve el mismo objeto, como se sugirió en el último comentario. Así que este método efectivamente hace una copia mezclada .

NotANumber avatar Jul 11 '2018 16:07 NotANumber