Existe uma maneira preferida de manter o tipo de dados de uma numpy
matriz fixo como int
( int64
ou qualquer outro), enquanto ainda tem um elemento listado como numpy.NaN
?
Em particular, estou convertendo uma estrutura de dados interna em um DataFrame do Pandas. Em nossa estrutura, temos colunas do tipo inteiro que ainda possuem NaNs (mas o tipo de coluna é int). Parece reformular tudo como um float se fizermos deste um DataFrame, mas realmente gostaríamos de ser int
.
Pensamentos?
As coisas tentaram:
Eu tentei usar a from_records()
função em pandas.DataFrame, com coerce_float=False
e isso não ajudou. Também tentei usar matrizes mascaradas NumPy, com NaN fill_value, que também não funcionou. Tudo isso fez com que o tipo de dados da coluna se tornasse flutuante.
from_records
função em pandas.DataFrame, comcoerce_float=False
, mas sem sorte ... ainda faz com que os novos dados tenham tipofloat64
.Respostas:
Este recurso foi adicionado aos pandas (começando na versão 0.24): https://pandas.pydata.org/pandas-docs/version/0.24/whatsnew/v0.24.0.html#optional-integer-na-support
Neste ponto, requer o uso da extensão dtype Int64 (maiúscula), em vez do padrão dtype int64 (minúscula).
fonte
'Int64'
para fazê-lo funcionar. Será ainda melhor quando será ativado por padrão.'Int64'
ou existe algo parecido'Int8'
? Ele usa uma quantidade insana de memória em comparação comnp.float
.'Int8'
parece funcionar, masnp.float
ainda parece carregar muito mais rápido. Parece que o problema não está liberando memória no meio. Suponha que o coletor de lixo acabe sendo executado.NaN
não pode ser armazenado em uma matriz inteira. Essa é uma limitação conhecida dos pandas no momento; Eu estava esperando o progresso com os valores de NA no NumPy (semelhante aos NAs no R), mas levará pelo menos seis meses a um ano até o NumPy obter esses recursos, parece:http://pandas.pydata.org/pandas-docs/stable/gotchas.html#support-for-integer-na
(Esse recurso foi adicionado a partir da versão 0.24 do pandas, mas observe que ele requer o uso da extensão dtype Int64 (maiúscula), em vez do padrão dtype int64 (minúscula): https://pandas.pydata.org/pandas- docs / version / 0.24 / whatsnew / v0.24.0.html # opcional-inteiro-na-suporte )
fonte
Se o desempenho não for o problema principal, você poderá armazenar as strings.
Então você pode misturar com o
NaN
quanto quiser. Se você realmente deseja ter números inteiros, dependendo do seu aplicativo, pode usar-1
, ou0
, ou1234567890
, ou algum outro valor dedicado para representarNaN
.Você também pode duplicar temporariamente as colunas: uma como você, com flutuadores; o outro experimental, com ints ou strings. Em seguida, insere
asserts
em todos os locais razoáveis, verificando se os dois estão sincronizados. Após testes suficientes, você pode soltar os flutuadores.fonte
Esta não é uma solução para todos os casos, mas as minhas (coordenadas genômicas) recorri ao uso de 0 como NaN
Isso pelo menos permite que o tipo de coluna 'nativo' apropriado seja usado, operações como subtração, comparação etc. funcionam como esperado
fonte
Pandas v0.24 +
A funcionalidade para suportar
NaN
séries inteiras estará disponível na v0.24 para cima. Há informações sobre isso na seção "Novidades" da v0.24 e mais detalhes em Tipo de dados inteiro nulo .Pandas v0.23 e anterior
Em geral, é melhor trabalhar com
float
séries onde for possível, mesmo quando a série é upcastint
dafloat
devido à inclusão deNaN
valores. Isso permite cálculos vetorizados baseados em NumPy onde, caso contrário, os loops no nível do Python seriam processados.Os documentos sugerem : "Uma possibilidade é usar
dtype=object
matrizes." Por exemplo:Por razões cosméticas, por exemplo, saída para um arquivo, isso pode ser preferível.
Pandas v0.23 e anterior: plano de fundo
NaN
é considerado afloat
. Os documentos atualmente (a partir da v0.23) especificam o motivo pelo qual a série inteira é convertida parafloat
:Os documentos também fornecem regras para upcasting devido à
NaN
inclusão:fonte
Isso agora é possível, pois o pandas v 0.24.0
notas de versão do pandas 0.24.x Citação: "O Pandas ganhou a capacidade de armazenar tipos inteiros com valores ausentes.
fonte
Só queria acrescentar que, caso você esteja tentando converter um vetor float (1.143) em número inteiro (1) que tenha NA convertendo para o novo dtype 'Int64', ocorrerá um erro. Para resolver isso, você deve arredondar os números e depois fazer ".astype ('Int64')"
Meu caso de uso é que tenho uma série flutuante que desejo arredondar para int, mas quando você faz .round () um '* .0' no final do número permanece, então você pode eliminar esse 0 do final até convertendo para int.
fonte
Se houver espaços em branco nos dados de texto, as colunas que normalmente seriam números inteiros serão convertidas em flutuantes como float64 dtype porque int64 dtype não pode manipular nulos. Isso pode causar um esquema inconsistente se você estiver carregando vários arquivos, alguns com espaços em branco (que acabarão como float64 e outros sem que acabarão como int64
Esse código tentará converter qualquer coluna de tipo numérico para Int64 (em oposição a int64), pois o Int64 pode manipular nulos
fonte