Eu tenho algum código Python que percorre uma lista de seqüências de caracteres e os converte em números inteiros ou números de ponto flutuante, se possível. Fazer isso para números inteiros é muito fácil
if element.isdigit():
newelement = int(element)
Os números de ponto flutuante são mais difíceis. No momento, estou usando partition('.')
para dividir a string e verificando se um ou os dois lados são dígitos.
partition = element.partition('.')
if (partition[0].isdigit() and partition[1] == '.' and partition[2].isdigit())
or (partition[0] == '' and partition[1] == '.' and partition[2].isdigit())
or (partition[0].isdigit() and partition[1] == '.' and partition[2] == ''):
newelement = float(element)
Isso funciona, mas, obviamente, a declaração if é um pouco difícil. A outra solução que considerei é apenas agrupar a conversão em um bloco try / catch e ver se ela é bem-sucedida, conforme descrito nesta pergunta .
Alguém tem outras ideias? Opiniões sobre os méritos relativos da partição e abordagens try / catch?
fonte
Método Python para verificar se há float:
Não fique mordido pelos goblins que se escondem no barco flutuador! FAÇA O TESTE DA UNIDADE!
O que é e não é um flutuador pode surpreendê-lo:
fonte
isfloat(" 1.23 ")
eisfloat(" \n \t 1.23 \n\t\n")
. Útil em solicitações da web; não é necessário aparar espaços em branco primeiro.que retornará
true
apenas se houver um ou não '.' na sequência de dígitos.retornará
false
retornará
false
fonte
[i for i in df[i].apply(lambda x: str(x).replace('.','').isdigit()).any()]
TL; DR :
try: except:
método é o melhor método nativo do Python.Existe outro método disponível por meio de um módulo de terceiros chamado número rápido (divulgação, eu sou o autor); fornece uma função chamada isfloat . Eu peguei o exemplo mais unido descrito por Jacob Gabrielson nesta resposta , mas adicionei o
fastnumbers.isfloat
método. Devo também observar que o exemplo de Jacob não fazia justiça à opção regex porque na maioria das vezes esse exemplo era gasto em pesquisas globais por causa do operador de ponto ... Modifiquei essa função para fazer uma comparação mais justatry: except:
.Na minha máquina, a saída é:
Como você pode ver, o regex na verdade não é tão ruim quanto parecia originalmente e, se você tem uma necessidade real de velocidade, o
fastnumbers
método é muito bom.fonte
Se você se preocupou com o desempenho (e eu não estou sugerindo que você deveria), a abordagem baseada em tentativas é a vencedora (em comparação com a abordagem baseada em partições ou a abordagem regexp), desde que você não espere muito seqüências inválidas, nesse caso, é potencialmente mais lento (provavelmente devido ao custo do tratamento de exceções).
Novamente, não estou sugerindo que você se preocupe com o desempenho, apenas fornecendo os dados para o caso de você fazer isso 10 bilhões de vezes por segundo, ou algo assim. Além disso, o código baseado em partição não manipula pelo menos uma sequência válida.
Aqui está o código (Python 2.6, regexp retirado da resposta de John Gietzen ):
fonte
Apenas por variedade, aqui está outro método para fazê-lo.
Edit: Tenho certeza de que ele não aguentará todos os casos de flutuação, especialmente quando houver um expoente. Para resolver isso, fica assim. Isso retornará True only val é um float e False para int, mas provavelmente tem menos desempenho que regex.
fonte
Este regex procurará números científicos de ponto flutuante:
No entanto, acredito que sua melhor aposta é usar o analisador em uma tentativa.
fonte
Se você não precisar se preocupar com expressões científicas ou outras expressões de números e estiver trabalhando apenas com strings que poderiam ser números com ou sem um período:
Função
Versão Lambda
Exemplo
Dessa forma, você não está convertendo acidentalmente o que deveria ser um int, em um float.
fonte
Versão simplificada da função
is_digit(str)
, que é suficiente na maioria dos casos (não considera notação exponencial e valor "NaN" ):fonte
Eu usei a função já mencionada, mas logo noto que cadeias de caracteres como "Nan", "Inf" e sua variação são consideradas como número. Então, proponho a você uma versão aprimorada da função, que retornará false nesse tipo de entrada e não falhará nas variantes "1e3":
fonte
if text.isalpha():
cheque imediatamente?Tente converter para flutuar. Se houver um erro, imprima a exceção ValueError.
Resultado:
fonte
Passando o dicionário como argumento, ele converterá seqüências de caracteres que podem ser convertidas em float e deixarão outras
fonte
Eu estava procurando por um código semelhante, mas parece que usar try / excpts é a melhor maneira. Aqui está o código que estou usando. Inclui uma função de repetição se a entrada for inválida. Eu precisava verificar se a entrada era maior que 0 e, se sim, convertê-la em um flutuador.
fonte
fonte
Tentei algumas das opções simples acima, usando um teste try para converter para um float e descobri que há um problema na maioria das respostas.
Teste simples (seguindo as linhas das respostas acima):
O problema surge quando:
Você está tentando então o
float('-')
que falhaVocê está tentando o
float('')
que também falhaA solução rápida que tive foi:
fonte
parece ser simples.
Manipula valores armazenados como uma string ou int ou float
fonte