Eu tenho o seguinte DataFrame, onde uma das colunas é um objeto (célula do tipo lista):
df=pd.DataFrame({'A':[1,2],'B':[[1,2],[1,2]]})
df
Out[458]:
A B
0 1 [1, 2]
1 2 [1, 2]
Minha saída esperada é:
A B
0 1 1
1 1 2
3 2 1
4 2 2
O que devo fazer para conseguir isso?
Questão relacionada
pandas: quando o conteúdo da célula é uma lista, crie uma linha para cada elemento da lista
Boa pergunta e resposta, mas lidar apenas com uma coluna com lista (em minha resposta a função de autodefinição funcionará para várias colunas, também a resposta aceita é a que consome mais tempo apply
, o que não é recomendado, verifique mais informações Quando devo querer usar pandas apply () em meu código? )
Respostas:
Como um usuário de
R
epython
, já vi esse tipo de pergunta algumas vezes.Em R, eles têm a função interna do pacote
tidyr
chamadaunnest
. Mas emPython
(pandas
) não há função incorporada para este tipo de pergunta.Sei que as
object
colunastype
sempre tornam os dados difíceis de converter com umapandas
função '. Quando recebi dados como esses, a primeira coisa que me veio à mente foi 'nivelar' ou desaninhar as colunas.Estou usando
pandas
epython
funções para este tipo de pergunta. Se você está preocupado com a velocidade das soluções acima, verifique a resposta do usuário3483203, pois ele está usandonumpy
e na maioria das vezesnumpy
é mais rápido. Eu recomendoCpython
enumba
se a velocidade é importante no seu caso.Método 0 [pandas> = 0,25]
Começando com pandas 0,25 , se você só precisa explodir uma coluna, pode usar a
explode
função:Método 1
apply + pd.Series
(fácil de entender, mas em termos de desempenho não recomendado).Método 2
Usando
repeat
com oDataFrame
construtor, recrie seu dataframe (bom em desempenho, não bom em colunas múltiplas)Método 2.1,
por exemplo, além de A, temos A.1 ..... An Se ainda usarmos o método ( Método 2 ) acima, será difícil recriar as colunas uma por uma.
Solução:
join
oumerge
com oindex
depois de 'unnest' as colunas individuaisSe você precisa da ordem das colunas exatamente como antes, adicione
reindex
no final.Método 3
recriar o
list
Se houver mais de duas colunas, use
Método 4
usando
reindex
ouloc
Método 5
quando a lista contém apenas valores únicos:
Método 6
usando
numpy
para alto desempenho:Método 7
usando a função de base
itertools
cycle
echain
: Solução Python pura apenas por diversãoGeneralizando para várias colunas
Função de autodefinição:
Desaninhamento de colunas
Todo o método acima está falando sobre o desninhamento vertical e explodir, se você precisar expandir a lista horizontal , verifique com o
pd.DataFrame
construtorFunção atualizada
Resultado do teste
fonte
ValueError: zero-dimensional arrays cannot be concatenated
. Além disso, poucos deles tentam generalizar para um dataframe mais amplo. Os que afirmam ainda exigem que você saiba com antecedência quantas colunas seu df possui.[]
deveria ser cair, você realmente tentou o exemplo, do meu? Ou você tem situação diferente?Opção 1
Se todas as sublistas na outra coluna tiverem o mesmo comprimento,
numpy
pode ser uma opção eficiente aqui:opção 2
Se as sublistas tiverem comprimentos diferentes, você precisará de uma etapa adicional:
Opção 3
Tentei generalizar isso para trabalhar para nivelar
N
colunas eM
colunas de ladrilhos , irei trabalhar mais tarde para torná-lo mais eficiente:Funções
Horários
atuação
fonte
df.explode
método.A explosão de uma coluna em forma de lista foi simplificada significativamente no pandas 0,25 com a adição do
explode()
método:Fora:
fonte
Uma alternativa é aplicar a receita meshgrid sobre as linhas das colunas para desaninhar:
Resultado
fonte
Meus 5 centavos:
e mais 5
ambos resultando no mesmo
fonte
Porque normalmente os comprimentos das sublistas são diferentes e a junção / fusão é muito mais dispendiosa em termos computacionais. Testei novamente o método para sub-listas de diferentes comprimentos e colunas mais normais.
MultiIndex deve ser também uma maneira mais fácil de escrever e tem quase o mesmo desempenho que a maneira numpy.
Surpreendentemente, na minha forma de compreensão de implementação tem o melhor desempenho.
atuação
Tempo relativo de cada método
fonte
Eu generalizei um pouco o problema para ser aplicável a mais colunas.
Resumo do que minha solução faz:
Exemplo completo:
A explosão real é realizada em 3 linhas. O resto é cosmético (explosão em várias colunas, manuseio de strings em vez de listas na coluna de explosão, ...).
Créditos à resposta do WeNYoBen
fonte
Configuração de problema
Suponha que haja várias colunas com objetos de diferentes comprimentos dentro dela
Quando os comprimentos são iguais, é fácil assumirmos que os vários elementos coincidem e devem ser "compactados" juntos.
No entanto, a suposição é questionada quando vemos objetos de comprimento diferente, devemos "zipar", em caso afirmativo, como tratamos o excesso em um dos objetos. OU , talvez queiramos o produto de todos os objetos. Isso vai aumentar rapidamente, mas pode ser o que se deseja.
OU
A função
Esta função lida graciosamente
zip
ou comproduct
base em um parâmetro e assume dezip
acordo com o comprimento do objeto mais longo comzip_longest
Compactado
produtos
Nova Configuração
Variando o exemplo um pouco
Compactado
produtos
fonte
Algo não muito recomendado (pelo menos funcione neste caso):
concat
+sort_index
+iter
+apply
+next
.Agora:
É:
Se você se preocupa com o índice:
Agora:
É:
fonte
Alguma opinião sobre este método que pensei? ou fazer concat e derreter é considerado muito "caro"?
fonte
fonte
fonte
No meu caso, com mais de uma coluna para explodir e com comprimentos variáveis para os arrays que precisam ser desaninhados.
Acabei aplicando a nova
explode
função pandas 0,25 duas vezes, removendo as duplicatas geradas e ela fez o trabalho!fonte
Eu tenho outra boa maneira de resolver isso quando você tem mais de uma coluna para explodir.
Eu quero explodir as colunas B e C. Primeiro eu explodo B, segundo C. Em seguida, removo B e C do df original. Depois disso, farei uma junção de índice nos 3 dfs.
fonte