2017-01-24 14 views
0

Мне известно о Python с ошибками с плавающей запятой при использовании обычных типов. Вот почему я использую Панды.Поля Float64 с ошибками с плавающей запятой в Pandas [Python]

я вдруг возникли некоторые проблемы с входными данными I (не расчет) и не может объяснить следующее поведение:

In [600]: df = pd.DataFrame([[0.05], [0.05], [0.05], [0.05]], columns = ['a']) 

In [601]: df.dtypes 
Out[601]: 
a float64 
dtype: object 

In [602]: df['a'].sum() 
Out[602]: 0.20000000000000001 

In [603]: df['a'].round(2).sum() 
Out[603]: 0.20000000000000001 

In [604]: (df['a'] * 1000000).round(0).sum() 
Out[604]: 200000.0 

In [605]: (df['a'] * 1000000).round(0).sum()/1000000 
Out[605]: 0.20000000000000001 

Надеюсь кто-нибудь может мне помочь либо исправить или выяснить, как правильно подводить 0,2 (или Я не возражаю, если результат равен 20 или 2000, но, как вы можете видеть, когда я делюсь, я попадаю в ту же точку, где сумма неверна!).

(запустить свой код, не забудьте сделать import pandas as pd)

+2

Это характер чисел с плавающей запятой. Это просто представление, поэтому вы можете игнорировать его. Почему это проблема для вас? BTW попробуйте это: 'print (0.1 + 0.2)' – MaxU

+0

@MaxU Получаю, что Макс. поэтому я постараюсь решить, если сделать 0.05 * 100 = 5, суммировать эти 4 и получить 20. Но моя проблема заключается в том, что система видит 20.00000..001, и даже округление не похоже на трюк. – Yona

+0

Возможный дубликат [Является ли математика с плавающей запятой?] (Http://stackoverflow.com/questions/588004/is-floating-point-math-broken) –

ответ

0

Ok так это работает:

In [642]: (((df * 1000000).round(0))/1000000).sum() 
Out[642]: 
a 0.2 
dtype: float64 

Но это не делает:

In [643]: (((df * 1000000).round(0))).sum() * 1000000 
Out[643]: 
a 2.000000e+11 
dtype: float64 

Таким образом, вы должны сделать все расчеты внутри массива Panda или подвергать риску разрушение вещей.

0

«Я добираюсь до той же точки, где сумма неверна!» По вашему определению неверных почти все операции с плавающей запятой были бы неверными. Только силы 2 отлично представлены плавающими точками, все остальное имеет ошибку округления около 15-17 знаков после запятой (для плавающих по двойной точности). Некоторые приложения просто скрывают эту ошибку лучше других при отображении этих значений. Эта точность намного больше, чем достаточно для данных, которые вы используете.

Если вас беспокоит уродливый вывод, вы можете сделать "{:.1f}".format(value), чтобы округлить строку вывода до 1 десятичной цифры после точки или "{:g}".format(value), чтобы автоматически выбрать разумное количество цифр для отображения.

+0

«Только силы 2» немного занижает ее: есть приблизительно 18 миллиардов миллиардов действительных чисел, которые могут быть точно представлены в обычном формате с плавающей точкой IEEE 754 binary64. Только 2098 из этих 18 миллиардов миллиардов имеют полномочия 2. –