Barajar filas de DataFrame


Tengo el siguiente DataFrame:

    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 Type 1 están en la parte superior, seguidas de las filas con Type 2, seguidas de las filas con Type 3, etc.

Me gustaría barajar las filas del DataFrame, para que todos los Type estén mezclados. 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
...

Como se puede ver en el resultado, el orden de las filas se baraja, pero las columnas siguen siendo las mismas. No se si estoy explicando esto claramente. Dejar yo sé si no lo hago.

¿Cómo puedo lograr esto?

Author: JNevens, 2015-04-11

7 answers

La forma más idiomática de hacer esto con pandas es usar el método .sample de su dataframe, es decir,

df.sample(frac=1)

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

Nota: Si desea barajar su dataframe en el lugar y restablecer el índice, puede hacer, por ejemplo,

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

Aquí, especificar drop=True evita que .reset_index cree una columna que contenga el índice anterior entrada.

 348
Author: Kris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-27 09:18:11

Simplemente puede usar sklearn para esto

from sklearn.utils import shuffle
df = shuffle(df)
 101
Author: tj89,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-24 07:42:10

Puede barajar las filas de un dataframe indexando con un índice barajado. Para esto, por ejemplo, puede usar np.random.permutation (pero np.random.choice tambié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)

 44
Author: joris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-11 10:26:59

TL;DR: np.random.shuffle(ndarray) puede hacer el trabajo.
Por lo tanto, en su caso

np.random.shuffle(DataFrame.values)

Según mi entendimiento, DataFrame, bajo el capó, utiliza NumPy ndarray como titular de datos. Puede comprobar desde DataFrame código fuente. Así que si utilizas np.random.shuffle(), barajaría la matriz a lo largo del primer eje de una matriz multidimensional. Pero las columnas siguen siendo las mismas.

Siguen algunas limitaciones.

  • la función devuelve none. En caso de que si desea conservar una copia del objeto original, debe hacerlo antes de pasar a la función.
  • sklearn.utils.shuffle() el usuario tj89 sugerido, puede designar random_state junto con otra opción para controlar la salida. Es posible que desee que para el propósito dev.

Resultado de referencia

, Entre sklearn.utils.shuffle() y np.random.shuffle().

Ndarray

nd = sklearn.utils.shuffle(nd)

0.10793248389381915 seg. 8 veces más rápido

np.random.shuffle(nd)

0.8897626010002568 sec

DataFrame

df = sklearn.utils.shuffle(df)

0.3183923360193148 seg. 3 veces más rápido

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

0,9357550159329548 sec

Conclusión: uso sklearn.utils.shuffle(), si es posible.

Código usado

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)

Pythonbenchmarking

 13
Author: haku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-23 06:07:48

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

df.sample(frac=1)

Hizo una copia profunda o simplemente cambió el dataframe. Corrí 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 es no devolviendo el mismo objeto, como se sugirió en el último comentario. Así que este método de hecho hace un barajado copia.

 3
Author: NotANumber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-11 16:31:32

AFAIK la solución más simple es:

df_shuffled = df.reindex(np.random.permutation(df.index))
 1
Author: Ido Cohn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-27 13:09:13

Barajar el marco de datos pandas tomando una matriz de muestra en este caso index y aleatorizar su orden y luego establecer la matriz como un índice de marco de datos. Ahora ordene el marco de datos de acuerdo con el índice. Aquí va su dataframe barajado

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()

Salida

    a   b
0   2   6
1   1   5
2   3   7
3   4   8

Inserte su marco de datos en el lugar de la mina en el código anterior .

 0
Author: Abhilash Reddy Yammanuru,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-13 11:28:40