Estou lendo um CSV com números flutuantes como este:
Bob,0.085
Alice,0.005
E importe para um dataframe e grave este dataframe em um novo lugar
df = pd.read_csv(orig)
df.to_csv(pandasfile)
Agora isso pandasfile
tem:
Bob,0.085000000000000006
Alice,0.0050000000000000001
O que acontece? talvez eu tenha que lançar para um tipo diferente, como float32 ou algo assim?
Estou usando o pandas 0.9.0 e o numpy 1.6.2 .
Respostas:
Conforme mencionado nos comentários, é um problema geral de ponto flutuante.
No entanto, você pode usar a
float_format
palavra-chave deto_csv
para ocultá-lo:df.to_csv('pandasfile.csv', float_format='%.3f')
ou, se você não quiser que 0,0001 seja arredondado para zero:
df.to_csv('pandasfile.csv', float_format='%g')
Darei à você:
Bob,0.085 Alice,0.005
em seu arquivo de saída.
Para obter uma explicação
%g
, consulte Minilinguagem de especificação de formato .fonte
TypeError: __init__() got an unexpected keyword argument 'float_format'
pandas
para uma versão mais recente.ATUALIZAÇÃO: a resposta estava correta no momento da escrita, e a precisão do ponto flutuante ainda não é algo que você obtém por padrão com to_csv / read_csv (compensação precisão-desempenho; padrões favorecem o desempenho).
Hoje em dia existe o
float_format
argumento disponível parapandas.DataFrame.to_csv
e ofloat_precision
argumento disponível parapandas.from_csv
.Vale a pena ler o original para entender melhor o problema.
Era um bug no pandas, não só na função "to_csv", mas também no "read_csv". Não é um problema geral de ponto flutuante, apesar de ser verdade que a aritmética de ponto flutuante é um assunto que exige alguns cuidados do programador. O artigo abaixo esclarece um pouco esse assunto:
http://docs.python.org/2/tutorial/floatingpoint.html
Um clássico que mostra o "problema" é ...
>>> 0.1 + 0.1 + 0.1 0.30000000000000004
... que não exibe 0,3 como seria de esperar. Por outro lado, se você lidar com o cálculo usando aritmética de ponto fixo e apenas na última etapa empregar aritmética de ponto flutuante , funcionará como você espera. Veja isso:
>>> (1 + 1 + 1) * 1.0 / 10 0.3
Se você precisa desesperadamente de contornar este problema, recomendo que você crie outro arquivo CSV que contenha todas as figuras como inteiros, por exemplo, multiplicando por 100, 1000 ou outro fator que seja conveniente. Dentro de seu aplicativo, leia o arquivo CSV normalmente e você receberá de volta os números inteiros. Em seguida, converta esses valores em ponto flutuante, dividindo pelo mesmo fator que você multiplicou antes.
fonte