Seleção aleatória de linhas no dataframe do Pandas

159

Existe uma maneira de selecionar linhas aleatórias de um DataFrame no Pandas.

Em R, usando o pacote car, existe uma função útil some(x, n)semelhante à cabeça, mas seleciona, neste exemplo, 10 linhas aleatoriamente de x.

Também examinei a documentação sobre fatias e parece não haver nada equivalente.

Atualizar

Agora usando a versão 20. Existe um método de amostra.

df.sample(n)

John
fonte
1
Se você estiver procurando amostras onde o tamanho é maior que o original, use df.sample(N, replace=True). Mais detalhes aqui .
cs95

Respostas:

57

Algo assim?

import random

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

Nota: A partir do Pandas v0.20.0, ix foi preterido em favor da locindexação baseada em rótulo.

eumiro
fonte
8
Obrigado @eumiro. Eu também descobri que df.ix[np.random.random_integers(0, len(df), 10)]também funcionaria.
John
7
Se você deseja usar numpy, também pode fazer df.ix[np.random.choice(df.index, 10)].
naught101
7
Alguém em um outro post mencionou que np.random.choiceé duas vezes mais rápidorandom.sample
Phani
5
Se você usar np.random.choice, precisará especificar replace = False, caso contrário, obterá linhas duplicadas!
stmax
2
Eu acho que ".ix" está obsoleta, e você deve usar .loc para a etiqueta com base indexação
compguy24
266

Com a versão pandas 0.16.1e superior, agora existe um 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 qualquer uma das abordagens acima, você pode obter o restante das linhas fazendo:

df_rest = df.loc[~df.index.isin(df_percent.index)]
ryanjdillon
fonte
df_0.7não é um nome válido. Além disso, sugiro substituir df_rest = df.loc[~df.index.isin(df_0_7.index)]por df_rest = df.loc[df.index.difference(df_0_7.index)].
Pietro Battiston
@PietroBattiston Thanks. Eu estava tentando esclarecer a resposta, mas concordo que um exemplo não útil não é claro. Bom com a dica sobre a diferença. No entanto, eu ainda prefiro escrever a fatia para que eu a leia como índices "não no índice da minha amostra". Existe um aumento de desempenho com difference()?
Ryanjdillon
1
@ryanjdillon houve um erro de digitação restante, eu consertei. Com relação ao método, na verdade, estou aceitando minha sugestão, pois, de fato, é um pouco menos eficiente. df_percent.index.get_indexer(df.index) == -1é muito mais eficiente em vez (mas também mais feio) ...
Pietro Battiston
18

sample

A partir da v0.20.0, é possível usar pd.DataFrame.sample, que pode ser usado para retornar uma amostra aleatória de um número fixo de linhas ou uma porcentagem de linhas:

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

Para reprodutibilidade, você pode especificar um número inteiro random_state, equivalente a usar np.ramdom.seed. Portanto, em vez de definir, por exemplo np.random.seed = 0, você pode:

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

A melhor maneira de fazer isso é com a função de amostra do módulo aleatório,

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
fonte
4

Na verdade, isso fornecerá índices repetidos np.random.random_integers(0, len(df), N)onde Nhá um número grande.

rlmlr
fonte
3

A linha abaixo selecionará aleatoriamente n número de linhas do total de números de linhas existentes no dataframe df sem substituição.

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

Mojgan Mazouchi
fonte