una seleccionar recorrer filas fila extraer eliminar data columnas borrar python pandas dataframe permutation shuffle

python - recorrer - seleccionar columnas de un dataframe pandas



Reproducción aleatoria de filas de DataFrame (9)

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 por las filas con Type 2, seguidas por las filas con Type 3, etc.

Me gustaría barajar el orden de las filas del DataFrame, para que todos los Type se mezclen. 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?


AFAIK la solución más simple es:

df_shuffled = df.reindex(np.random.permutation(df.index))


Aquí hay otra forma:

df[''rnd''] = np.random.rand(len(df)) df = df.sort_values(by=''rnd'', inplace=True).drop(''rnd'', axis=1)


La forma más idiomática de hacer esto con los pandas es usar el método .sample de su marco de datos, 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 marco de datos 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 las entradas de índice antiguas.

Nota de seguimiento: aunque puede no parecer que la operación anterior esté en su lugar , python / pandas es lo suficientemente inteligente como para no hacer otro malloc para el objeto barajado. Es decir, aunque el objeto de referencia ha cambiado (con lo que quiero decir que id(df_old) no es lo mismo que id(df_new) ), el objeto C subyacente sigue siendo el mismo. Para mostrar que este es 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)


Lo que también es útil, si lo usa para Machine_learning y desea separar siempre los mismos datos, puede usar:

df.sample(n=len(df), random_state=42)

esto asegura que mantengas tu opción aleatoria siempre replicable


Puede barajar las filas de un marco de datos indexando con un índice barajado. Para esto, puede usar, por ejemplo, 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)


Simplemente puede usar sklearn para esto

from sklearn.utils import shuffle df = shuffle(df)


baraja el marco de datos de pandas tomando una matriz de muestra en este caso índice y aleatoriza su orden y luego configura la matriz como un índice de marco de datos. Ahora ordene el marco de datos según el índice. Aquí va tu marco de datos 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 mío en el código anterior.


(No tengo suficiente reputación para comentar esto en la publicación principal, así que espero que alguien más pueda hacer eso por mí). Hubo una preocupación que surgió del primer método:

df.sample(frac=1)

hizo una copia profunda o simplemente cambió 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. Entonces, este método realmente hace una copia barajada.


TL; DR : np.random.shuffle(ndarray) puede hacer el trabajo.
Entonces, en tu caso

np.random.shuffle(DataFrame.values)

DataFrame , bajo el capó, utiliza NumPy ndarray como soporte de datos. (Puede verificar desde el código fuente de DataFrame )

Entonces, si usa np.random.shuffle() , np.random.shuffle() la matriz a lo largo del primer eje de una matriz multidimensional. Pero el índice del DataFrame permanece sin mezclar.

Sin embargo, hay algunos puntos a considerar.

  • La función no devuelve ninguno. En caso de que desee conservar una copia del objeto original, debe hacerlo antes de pasar a la función.
  • sklearn.utils.shuffle() , como sugirió el usuario tj89, puede designar random_state junto con otra opción para controlar la salida. Es posible que desee eso para fines de desarrollo.
  • sklearn.utils.shuffle() es más rápido. Pero CAMBIARÁ la información del eje (índice, columna) del DataFrame junto con el ndarray que contiene.

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 seg

Marco de datos

df = sklearn.utils.shuffle(df)

0.3183923360193148 seg. 3 veces más rápido

np.random.shuffle(df.values)

0.9357550159329548 sec

Conclusión: Si está bien ejemplificar la información (índice, columna) junto con ndarray, use sklearn.utils.shuffle() . De lo contrario, use np.random.shuffle()

código usado

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)

benchmarking python