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 .


26
Ласкаво просимо до номерів із плаваючою комою.
Ігнасіо Васкес-Абрамс


1
Я створив випуск для більш детального вивчення тут: github.com/pydata/pandas/issues/2069 EDIT: Якщо можете, будь ласка, розмістіть автономне відтворення проблеми у випуску GitHub. Я не можу його відтворити.
Wes McKinney

Відповіді:


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

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, як зазвичай, і ви отримаєте ці цілі цифри назад. Потім перетворіть ці значення в плаваючу крапку, поділивши на той самий коефіцієнт, який ви множили раніше.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.