Запись поплавков в csvs в python - ошибка усечения - PullRequest
1 голос
/ 14 марта 2012

Я столкнулся с проблемой, когда числа с плавающей точкой усекаются в процессе записи в csv.Это сложно воспроизвести, так как это случается редко с тысячами файлов, но мне нужна защита от этого.Вот пример того, как выглядит код:

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()

Исходя из выходных данных (в которых все числа обязательно меньше 1), он выглядит как последние символы в небольшом числе (т. Е. "...e-5 ") теряются:

draw373         draw374         draw375          draw376    
0.000744        0.003008        0.001566         9.727522

Любые предложения о том, как предотвратить это?

Ответы [ 2 ]

2 голосов
/ 14 марта 2012

Я бы предложил использовать для этого csv-писатель numpy. Например:

>>> 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()

Это правильно сериализует номера. Вы также можете передать строку формата в savetxt, чтобы указать способ печати значений с плавающей запятой.

1 голос
/ 14 марта 2012

Проблема заключается в преобразовании между десятичным представлением числа и представлением в памяти.

Вы можете получить более подробную информацию о реализации float в python: http://docs.python.org/library/sys.html#sys.float_info

Существует такжевсеобъемлющее руководство по плавающим точкам: http://docs.python.org/tutorial/floatingpoint.html

Особенно я рекомендую вам раздел "Ошибка представления"

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

Если ваше приложение требует высокой точности, вы можете использовать:

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