Eu tenho o seguinte 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
...
O DataFrame é lido de um arquivo CSV. Todas as linhas que possuem Type
1 estão no topo, seguidas pelas linhas com Type
2, seguidas pelas linhas com Type
3, etc.
Gostaria de embaralhar a ordem das linhas do DataFrame, para que todas Type
sejam misturadas. Um resultado possível pode 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 posso conseguir isso?
.copy()
ainda fará referência ao mesmo objeto subjacente.Você pode simplesmente usar o sklearn para isso
fonte
Você pode embaralhar as linhas de um quadro de dados indexando com um índice embaralhado. Para isso, você pode, por exemplo, usar
np.random.permutation
(masnp.random.choice
também é uma possibilidade):Se você deseja manter o índice numerado de 1, 2, .., n como no seu exemplo, você pode simplesmente redefinir o índice:
df_shuffled.reset_index(drop=True)
fonte
TL; DR :
np.random.shuffle(ndarray)
pode fazer o trabalho.Então, no seu caso
DataFrame
, sob o capô, usa o NumPy ndarray como suporte para dados. (Você pode verificar no código-fonte do DataFrame )Portanto, se você usar
np.random.shuffle()
, ele embaralha a matriz ao longo do primeiro eixo de uma matriz multidimensional. Mas o índice dosDataFrame
restos não foi baralhado.No entanto, existem alguns pontos a considerar.
sklearn.utils.shuffle()
, como o usuário tj89 sugeriu, pode designarrandom_state
junto com outra opção para controlar a saída. Você pode querer isso para fins de desenvolvimento.sklearn.utils.shuffle()
é mais rápido. Porém, embaralhará as informações do eixo (índice, coluna) doDataFrame
junto com o quendarray
ele contém.Resultado de referência
entre
sklearn.utils.shuffle()
enp.random.shuffle()
.ndarray
0,10793248389381915 seg. 8x mais rápido
0,897626010002568 seg
Quadro de dados
0,3183923360193148 seg. 3x mais rápido
0.9357550159329548 sec
código usado
Pitãoavaliação comparativa
fonte
df = df.sample(frac=1)
faz exatamente a mesma coisa quedf = sklearn.utils.shuffle(df)
? De acordo com minhas medidas,df = df.sample(frac=1)
é mais rápido e parece executar exatamente a mesma ação. Eles também alocam nova memória.np.random.shuffle(df.values)
é o mais lento, mas não aloca nova memória.df.sample(frac=1)
é cerca de 20% mais rápido quesklearn.utils.shuffle(df)
, usando o mesmo código acima. Ou você poderia fazersklearn.utils.shuffle(ndarray)
para obter resultados diferentes.(Eu não tenho reputação suficiente para comentar isso na postagem principal, então espero que outra pessoa possa fazer isso por mim.) Houve uma preocupação quanto ao primeiro método:
fez uma cópia profunda ou apenas alterou o quadro de dados. Eu executei o seguinte código:
e meus resultados foram:
o que significa que o método não está retornando o mesmo objeto, como foi sugerido no último comentário. Portanto, esse método realmente faz uma cópia aleatória .
fonte
id
), o objeto subjacente não é copiado. Em outras palavras, a operação está efetivamente na memória (embora seja certo que não é óbvio).O que também é útil, se você o usar para Machine_learning e quiser separar sempre os mesmos dados, poderá usar:
isso garante que você mantenha sua escolha aleatória sempre replicável
fonte
AFAIK, a solução mais simples é:
fonte
np.random.permutation
: "... Se x for uma matriz, faça uma cópia e embaralhe os elementos aleatoriamente". Documentação deDataFrame.reindex
: "Um novo objeto é produzido, a menos que o novo índice seja equivalente ao atual e copy = False". Portanto, a resposta é perfeitamente segura (embora produza uma cópia).np.random.permutation says
e, dependendo das versões do numpy, você obtém o efeito que eu descrevi ou o que você mencionou. Com numpy> 1.15.0, criando um quadro de dados e fazendo uma planícienp.random.permutation(df.index)
, os índices no df original são alterados. O mesmo não ocorre para numpy == 1.14.6. Então, mais do que nunca, repito meu aviso: esse modo de fazer as coisas é perigoso por causa de efeitos colaterais imprevistos e dependências de versão.Index
tipo de ... Em qualquer caso, eu baseio minhas recomendações / avisos sobre o comportamento real, não nos docs: pembaralhe o quadro de dados do pandas, pegando uma matriz de amostra nesse índice de caso e aleatoriamente sua ordem, em seguida, defina a matriz como um índice do quadro de dados. Agora classifique o quadro de dados de acordo com o índice. Aqui vai o seu dataframe embaralhado
resultado
Insira seu quadro de dados no meu local no código acima.
fonte
Aqui está outra maneira:
df['rnd'] = np.random.rand(len(df)) df = df.sort_values(by='rnd', inplace=True).drop('rnd', axis=1)
fonte