float64 с пандами to_csv

88

Я читаю CSV с такими числами с плавающей запятой:

Bob,0.085
Alice,0.005

И импортируйте в фрейм данных и запишите этот фрейм данных в новое место

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

Теперь это pandasfile:

Bob,0.085000000000000006
Alice,0.0050000000000000001

Что случилось? возможно, мне нужно использовать другой тип, например float32 или что-то в этом роде?

Я использую pandas 0.9.0 и numpy 1.6.2 .

avances123
источник
26
Добро пожаловать в числа с плавающей запятой.
Игнасио Васкес-Абрамс,
1
Дубликат stackoverflow.com/questions/1778368/…
Натан Вильяэскуса
1
Я создал проблему для более подробного изучения здесь: github.com/pydata/pandas/issues/2069 РЕДАКТИРОВАТЬ: Если можете, поместите автономное воспроизведение проблемы в выпуск GitHub. Я не могу это воспроизвести.
Уэс МакКинни,

Ответы:

165

Как упоминалось в комментариях, это общая проблема с плавающей запятой.

Однако вы можете использовать float_formatключевое слово, to_csvчтобы скрыть это:

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

или, если вы не хотите, чтобы 0,0001 округлялся до нуля:

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

даст тебе:

Bob,0.085
Alice,0.005

в вашем выходном файле.

Для объяснения %g, см. Мини-язык спецификации формата .

БМУ
источник
Получил ошибкуTypeError: __init__() got an unexpected keyword argument 'float_format'
wander95
Если у кого-то такая же ошибка, как у @ wander95, вероятно, вам нужно обновить ее pandasдо более новой версии.
driftcatcher 06
10

ОБНОВЛЕНИЕ: ответ был точным на момент написания, и точность с плавающей запятой по-прежнему не является тем, что вы получаете по умолчанию с to_csv / read_csv (компромисс между точностью и производительностью; по умолчанию предпочтение отдается производительности).

В настоящее время существует аргумент для и аргумент для .float_formatpandas.DataFrame.to_csvfloat_precisionpandas.from_csv

Оригинал все же стоит прочитать, чтобы лучше понять проблему.


Это была ошибка в пандах, не только в функции «to_csv», но и в «read_csv». Это не общая проблема с плавающей запятой, хотя правда, что арифметика с плавающей запятой - это предмет, требующий некоторой осторожности от программиста. Эта статья ниже немного разъясняет эту тему:

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

Классический однострочный текст, показывающий "проблему" ...

>>> 0.1 + 0.1 + 0.1
0.30000000000000004

... который не отображает 0,3, как можно было бы ожидать. С другой стороны, если вы обрабатываете вычисления с использованием арифметики с фиксированной запятой и только на последнем этапе вы используете арифметику с плавающей запятой , все будет работать так, как вы ожидаете. Видеть это:

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

Если вам отчаянно нужно обойти эту проблему, я рекомендую вам создать другой файл CSV, который будет содержать все цифры как целые числа, например, умножение на 100, 1000 или другой коэффициент, который окажется удобным. Внутри вашего приложения прочтите файл CSV как обычно, и вы получите эти целые числа обратно. Затем преобразуйте эти значения в числа с плавающей запятой, разделив их на тот же коэффициент, который вы умножили ранее.

Ричард Гомес
источник