float64 avec pandas to_csv

88

Je lis un CSV avec des nombres flottants comme celui-ci:

Bob,0.085
Alice,0.005

Et importez dans un dataframe, et écrivez ce dataframe dans un nouvel endroit

df = pd.read_csv(orig)
df.to_csv(pandasfile)

Maintenant, cela pandasfilea:

Bob,0.085000000000000006
Alice,0.0050000000000000001

Qu'est-ce qui se passe? peut-être que je dois lancer un type différent comme float32 ou quelque chose?

Im en utilisant pandas géants 0.9.0 et numpy 1.6.2 .

avances123
la source
26
Bienvenue aux nombres à virgule flottante.
Ignacio Vazquez-Abrams
1
Duplicata de stackoverflow.com/questions/1778368/…
Nathan Villaescusa
1
J'ai créé un problème à examiner un peu plus en détail ici: github.com/pydata/pandas/issues/2069 EDIT: Si vous le pouvez, veuillez mettre une reproduction autonome du problème sur le problème GitHub. Je ne peux pas le reproduire.
Wes McKinney

Réponses:

165

Comme mentionné dans les commentaires, il s'agit d'un problème général en virgule flottante.

Cependant vous pouvez utiliser le float_formatmot clé de to_csvpour le masquer:

df.to_csv('pandasfile.csv', float_format='%.3f')

ou, si vous ne voulez pas que 0,0001 soit arrondi à zéro:

df.to_csv('pandasfile.csv', float_format='%g')

te donnera:

Bob,0.085
Alice,0.005

dans votre fichier de sortie.

Pour une explication de %g, voir Format Specification Mini-Language .

bmu
la source
J'ai une erreurTypeError: __init__() got an unexpected keyword argument 'float_format'
wander95
Si quelqu'un a la même erreur que @ wander95, vous devez probablement mettre pandasà jour vers une version plus récente.
driftcatcher
10

MISE À JOUR: La réponse était précise au moment de l'écriture, et la précision en virgule flottante n'est toujours pas quelque chose que vous obtenez par défaut avec to_csv / read_csv (compromis précision-performances; les valeurs par défaut favorisent les performances).

De nos jours, il y a l' float_formatargument disponible pourpandas.DataFrame.to_csv et l' float_precisionargument disponible pourpandas.from_csv .

L'original vaut toujours la peine d'être lu pour mieux appréhender le problème.


C'était un bug dans les pandas, non seulement dans la fonction "to_csv", mais aussi dans "read_csv". Ce n'est pas un problème général en virgule flottante, même s'il est vrai que l' arithmétique en virgule flottante est un sujet qui demande une certaine attention de la part du programmeur. Cet article ci-dessous clarifie un peu ce sujet:

http://docs.python.org/2/tutorial/floatingpoint.html

Un one-liner classique qui montre le "problème" est ...

>>> 0.1 + 0.1 + 0.1
0.30000000000000004

... qui n'affiche pas 0,3 comme on pourrait s'y attendre. D'un autre côté, si vous gérez le calcul en utilisant l' arithmétique en virgule fixe et que vous n'utilisez l' arithmétique en virgule flottante qu'à la dernière étape , cela fonctionnera comme prévu. Regarde ça:

>>> (1 + 1 + 1)  * 1.0 / 10
0.3

Si vous avez désespérément besoin de contourner ce problème, je vous recommande de créer un autre fichier CSV contenant tous les chiffres sous forme d'entiers, par exemple en multipliant par 100, 1000 ou tout autre facteur qui s'avère pratique. Dans votre application, lisez le fichier CSV comme d'habitude et vous récupérerez ces nombres entiers. Puis convertissez ces valeurs en virgule flottante, en divisant par le même facteur que vous avez multiplié auparavant.

Richard Gomes
la source