Estou tentando transformar uma célula do pandas contendo uma lista em linhas para cada um desses valores.
Então, pegue isto:
Se eu gostaria de descompactar e empilhar os valores na nearest_neighbors
coluna de forma que cada valor fosse uma linha dentro de cada opponent
índice, qual seria a melhor maneira de fazer isso? Existem métodos do pandas destinados a operações como essa?
pd.DataFrame(df.nearest_neighbors.values.tolist())
para descompactar esta coluna e, em seguida,pd.merge
colá-la com as outras.values.tolist()
que não faz nada aqui; a coluna já é uma listaRespostas:
No código abaixo, primeiro redefino o índice para tornar a iteração da linha mais fácil.
Eu crio uma lista de listas em que cada elemento da lista externa é uma linha do DataFrame de destino e cada elemento da lista interna é uma das colunas. Essa lista aninhada será finalmente concatenada para criar o DataFrame desejado.
Eu uso uma
lambda
função junto com a iteração de lista para criar uma linha para cada elemento donearest_neighbors
par com oname
e relevanteopponent
.Por fim, crio um novo DataFrame a partir dessa lista (usando os nomes das colunas originais e configurando o índice de volta para
name
eopponent
).EDITAR JUNHO DE 2017
Um método alternativo é o seguinte:
fonte
apply(pd.Series)
está bem no menor dos quadros, mas para qualquer quadro de tamanho razoável, você deve reconsiderar uma solução de melhor desempenho. Consulte Quando devo usar o pandas apply () em meu código? (Uma solução melhor é listar a coluna primeiro.)explode()
método. Eu adicionei uma resposta com um exemplo usando a mesma configuração de df como aqui.Use
apply(pd.Series)
estack
, entãoreset_index
eto_frame
Detalhes
fonte
df.nearest_neighbors.apply(pd.Series)
é muito surpreendente para mim;explode()
método:Fora:
fonte
Eu acho que essa é uma pergunta muito boa, no Hive você usaria
EXPLODE
, eu acho que é preciso argumentar que o Pandas deve incluir essa funcionalidade por padrão. Eu provavelmente explodiria a coluna da lista com uma compreensão de gerador aninhado como esta:fonte
O método mais rápido que encontrei até agora é estender o DataFrame com
.iloc
e atribuir de volta o plano coluna alvo.Dada a entrada usual (replicada um pouco):
Dadas as seguintes alternativas sugeridas:
Acho que
extend_iloc()
é o mais rápido :fonte
cols = [c for c in df.columns if c != col_target]
deveria ser:cols = [i for i,c in enumerate(df.columns) if c != col_target]
Osdf.iloc[ilocations, cols].copy()
erros não são apresentados com o índice da coluna.Solução alternativa mais agradável com aplicar (pd.Series):
fonte
Semelhante à funcionalidade EXPLODE do Hive:
fonte
NameError: global name 'copy' is not defined
Todas essas respostas são boas, mas eu queria algo ^ realmente simples ^ então aqui está minha contribuição:
É isso .. apenas use isso quando quiser uma nova série onde as listas são 'explodidas'. Aqui está um exemplo onde fazemos value_counts () nas escolhas do taco :)
fonte
Aqui está uma otimização potencial para dataframes maiores. Isso é executado mais rápido quando há vários valores iguais no campo "explodindo". (Quanto maior for o dataframe em comparação com a contagem de valor exclusivo no campo, melhor será o desempenho desse código.)
fonte
Estendendo a
.iloc
resposta de Oleg para nivelar automaticamente todas as colunas da lista:Isso pressupõe que cada coluna da lista tenha o mesmo comprimento de lista.
fonte
Em vez de usar apply (pd.Series), você pode nivelar a coluna. Isso melhora o desempenho.
fonte