Eu tenho um DataFrame com muitos valores ausentes nas colunas que desejo agrupar:
import pandas as pd
import numpy as np
df = pd.DataFrame({'a': ['1', '2', '3'], 'b': ['4', np.NaN, '6']})
In [4]: df.groupby('b').groups
Out[4]: {'4': [0], '6': [2]}
veja que o Pandas eliminou as linhas com os valores alvo de NaN. (Eu quero incluir essas linhas!)
Como preciso de muitas dessas operações (muitas colunas têm valores ausentes) e utilizo funções mais complicadas do que apenas medianas (geralmente florestas aleatórias), quero evitar escrever partes de código muito complicadas.
Alguma sugestão? Devo escrever uma função para isso ou existe uma solução simples?
dropna=False
emgroupby()
obter o resultado desejado. Mais informaçõesRespostas:
Isso é mencionado na seção Dados ausentes dos documentos :
Uma solução alternativa é usar um espaço reservado antes de fazer o groupby (por exemplo, -1):
Dito isso, isso parece um hack horrível ... talvez deva haver uma opção para incluir o NaN no groupby (veja este problema do github - que usa o mesmo hack do espaço reservado).
fonte
Tópico antigo, se alguém ainda tropeçar nisso - outra solução alternativa é converter via .astype (str) em string antes de agrupar. Isso conservará os NaNs.
fonte
sum
dea
é uma concatenação de string aqui, não uma soma numérica. Isso apenas "funciona" porque 'b' consistia em entradas distintas. Você precisa de 'a' a ser numérico e 'b' para ser cordapandas> = 1.1
No pandas 1.1, você terá melhor controle sobre esse comportamento, agora os valores de NA são permitidos na garoupa usando
dropna=False
:Você pode instalar a versão de pré-lançamento da v1.1 usando o seguinte comando:
fonte
Não consigo adicionar um comentário a M. Kiewisch, pois não tenho pontos de reputação suficientes (só tenho 41, mas preciso de mais de 50 para comentar).
Enfim, só quero salientar que a solução M. Kiewisch não funciona como está e pode precisar de mais ajustes. Considere por exemplo
que mostra que, para o grupo b = 4,0, o valor correspondente é 15 em vez de 6. Aqui está apenas concatenando 1 e 5 como seqüências de caracteres, em vez de adicioná-lo como números.
fonte
b
colunaUm pequeno ponto na solução de Andy Hayden - ela não funciona (mais?) Porque
np.nan == np.nan
produzFalse
, então areplace
função não faz nada.O que funcionou para mim foi o seguinte:
(Pelo menos esse é o comportamento do Pandas 0.19.2. Desculpe adicioná-lo como uma resposta diferente, não tenho reputação suficiente para comentar.)
fonte
df['b'].fillna(-1)
.Todas as respostas fornecidas até agora resultam em comportamento potencialmente perigoso, pois é bem possível que você selecione um valor simulado que faça parte do conjunto de dados. É cada vez mais provável que você crie grupos com muitos atributos. Simplificando, a abordagem nem sempre generaliza bem.
Uma solução menos invasiva é usar pd.drop_duplicates () para criar um índice exclusivo de combinações de valores, cada um com seu próprio ID e, em seguida, agrupar esse ID. É mais detalhado, mas faz o trabalho:
Observe que agora você pode simplesmente fazer o seguinte:
Isso retornará o resultado bem-sucedido sem ter que se preocupar com a substituição de dados reais que são confundidos com um valor fictício.
fonte
Eu já respondi isso, mas por algum motivo a resposta foi convertida em um comentário. No entanto, esta é a solução mais eficiente:
Não ser capaz de incluir (e propagar) NaNs em grupos é bastante agravante. Citar R não é convincente, pois esse comportamento não é consistente com muitas outras coisas. Enfim, o truque falso também é muito ruim. No entanto, o tamanho (inclui NaNs) e a contagem (ignora NaNs) de um grupo serão diferentes se houver NaNs.
Quando estes diferem, você pode definir o valor novamente como Nenhum para o resultado da função de agregação para esse grupo.
fonte
Pandas 1.1 instalados no Anaconda
Não consigo comentar a resposta do cs95, mas ele me ajudou a resolver o problema.
Tentei instalar o Pandas 1.1, mas ele falhou ao usar o código dele, por isso pesquisei no Google e consegui instalar.
Primeiro, execute o prompt do anaconda como administrador e cole o seguinte código:
pip install pandas==1.1.0rc0
Depois disso, inclua o uso
dropna = False
Link: https://libraries.io/pypi/pandas
fonte
df = df.fillna("")
isso funcionou para mimfonte