Selección aleatoria de filas en el marco de datos de Pandas

159

¿Hay alguna manera de seleccionar filas aleatorias de un DataFrame en Pandas?

En R, usando el paquete de automóvil, hay una función útil some(x, n)que es similar a head pero selecciona, en este ejemplo, 10 filas al azar de x.

También he mirado la documentación de corte y parece que no hay nada equivalente.

Actualizar

Ahora usando la versión 20. Hay un método de muestra.

df.sample(n)

Juan
fuente
1
Si está buscando una muestra donde el tamaño es mayor que el original, use df.sample(N, replace=True). Más detalles aquí .
cs95

Respuestas:

57

¿Algo como esto?

import random

def some(x, n):
    return x.ix[random.sample(x.index, n)]

Nota: A partir de Pandas v0.20.0, ix ha quedado en desuso a favor de la locindexación basada en etiquetas.

eumiro
fuente
8
Gracias @eumiro. También resolví que eso df.ix[np.random.random_integers(0, len(df), 10)]también funcionaría.
John
77
Si quieres usar numpy, entonces también puedes hacerlo df.ix[np.random.choice(df.index, 10)].
naught101
77
Alguien en otra publicación mencionó que np.random.choicees dos veces más rápido querandom.sample
Phani
55
Si usa np.random.choice, debe especificar replace = False; de ​​lo contrario, obtendrá filas duplicadas.
stmax
2
Creo que ".ix" está en desuso, y debería usar .loc para la indexación basada en etiquetas
compguy24
266

Con la versión de pandas 0.16.1y superior, ahora hay un DataFrame.sample método incorporado :

import pandas

df = pandas.DataFrame(pandas.np.random.random(100))

# Randomly sample 70% of your dataframe
df_percent = df.sample(frac=0.7)

# Randomly sample 7 elements from your dataframe
df_elements = df.sample(n=7)

Para cualquiera de los enfoques anteriores, puede obtener el resto de las filas haciendo:

df_rest = df.loc[~df.index.isin(df_percent.index)]
ryanjdillon
fuente
df_0.7No es un nombre válido. Además, sugiero reemplazar df_rest = df.loc[~df.index.isin(df_0_7.index)]con df_rest = df.loc[df.index.difference(df_0_7.index)].
Pietro Battiston
@PietroBattiston Gracias. Intenté aclarar la respuesta, pero estoy de acuerdo en que un ejemplo que no funciona no está claro. Agradable con el consejo de la diferencia. Sin embargo, todavía prefiero escribir el corte para leerlo como índices "no en el índice de mi muestra". ¿Hay un aumento de rendimiento con difference()?
ryanjdillon
1
@ryanjdillon había un error tipográfico restante, lo arreglé. Con respecto al método, en realidad estoy retirando mi sugerencia, ya que de hecho es un poco menos eficiente. df_percent.index.get_indexer(df.index) == -1es mucho más eficiente en su lugar (pero también más feo) ...
Pietro Battiston
18

sample

A partir de v0.20.0, puede usar pd.DataFrame.sample, que puede usarse para devolver una muestra aleatoria de un número fijo de filas, o un porcentaje de filas:

df = df.sample(n=k)     # k rows
df = df.sample(frac=k)  # int(len(df.index) * k) rows

Para la reproducibilidad, puede especificar un número entero random_state, equivalente al uso np.ramdom.seed. Entonces, en lugar de configurar, por ejemplo, np.random.seed = 0puede:

df = df.sample(n=k, random_state=0)
jpp
fuente
7

La mejor manera de hacerlo es con la función de muestra del módulo aleatorio,

import numpy as np
import pandas as pd
from random import sample

# given data frame df

# create random index
rindex =  np.array(sample(xrange(len(df)), 10))

# get 10 random rows from df
dfr = df.ix[rindex]
rlmlr
fuente
4

En realidad, esto le dará índices repetidos np.random.random_integers(0, len(df), N)donde Nhay un gran número.

rlmlr
fuente
3

La línea inferior seleccionará aleatoriamente n número de filas del total de números de fila existentes del marco de datos df sin reemplazo.

df=df.take(np.random.permutation(len(df))[:n])

Mojgan Mazouchi
fuente