2012-03-13 4 views
1

Je rencontre un problème où les nombres flottants sont tronqués dans mon processus d'écriture csv. C'est difficile à reproduire, car cela arrive rarement dans des milliers de fichiers, mais j'ai besoin d'une protection contre cela. Voici un exemple de ce que le code ressemble à:Ecriture des flottants dans csvs dans python - erreur de troncature

import csv 
import numpy as np 
x = np.random.normal(0, .001, 1000).tolist() 
draws_header = ['draw%s'%(x) for x in range(1000)] 
final_output = np.array(x) 
outfile = open('filepath.csv', 'w') 
writer = csv.writer('filepath') 
writer.writerow(first_row) 
writer.writerows(final_output) 
outfile.close() 

Sur la base de la sortie (où tous les numéros ne sont pas nécessairement en dessous de 1), il semble que les derniers caractères dans un petit nombre (ie, » ... e-5 ") se perdent:

draw373   draw374   draw375   draw376  
0.000744  0.003008  0.001566   9.727522 

Des suggestions pour éviter cela?

Répondre

2

Je suggère d'utiliser l'auteur de csv de numpy pour cela. Par exemple:

>>> import numpy as np 
>>> x = np.random.normal(0, .001, 1000) 
>>> draws_header = ['draw%s'%(i) for i in range(1000)] 
>>> f = open('file.csv', 'w') 
>>> np.savetxt(f, np.array(draws_header)[:,None].T, fmt="%s", delimiter="\t") 
>>> np.savetxt(f, x[:,None].T, delimiter="\t") 
>>> f.close() 

Ceci sérialise correctement les nombres. Vous pouvez également passer une chaîne de format à savetxt pour spécifier comment imprimer vos valeurs à virgule flottante.

+0

Merci pour le pourboire - je vais lui donner un tourbillon. – mike

+0

Bonne réponse, mais il serait plus propre de cette façon: >>> np.savetxt (f, np.array ([draw_header]), fmt = "% s", délimiteur = "\ t") >>> np .savetxt (f, [x], délimiteur = "\ t") – Tickon

1

Le problème est la conversion entre la représentation décimale du nombre et la représentation en mémoire.

Vous pouvez obtenir plus de détails sur la mise en œuvre de python de son float: http://docs.python.org/library/sys.html#sys.float_info

Il y a aussi tutoriel complet sur les points flottants: http://docs.python.org/tutorial/floatingpoint.html

Surtout que je vous recommande la section "Erreur de représentation"

#input 
a = 0 
for x in xrange(10): 
    a += 0.1 
print a 
#output 
0.9999999999999999 

Si votre application nécessite une grande précision, vous pouvez utiliser:

#input 
from decimal import Decimal 
a = Decimal('0.0') 
for x in xrange(10): 
    a += Decimal('0.1') 
print a 
#output 
1.0 
Questions connexes