2

I would like to convert string (%) to float.but my method didnt work well. the result slightly differ from correct number. for example,

a=pd.Series(data=["0.1%","0.2%"])

0    0.1%
1    0.2%
dtype: object

first, I strip "%"

a.str.rstrip("%")

0    0.1
1    0.2
dtype: object

I tried to convert to numeric, but the result is strange.

I guess this phenomena come from binary digit system...

pd.to_numeric(a.str.rstrip("%"))

0    0.10000000000000000555
1    0.20000000000000001110
dtype: float64

and of course I couldnt convert % to numeric.

pd.to_numeric(a.str.rstrip("%"))/100

0    0.00100000000000000002
1    0.00200000000000000004
dtype: float64

I also tried .astype(float) method. but The result was same..

why this phenomena happen ? and how can I avoid this phenomena

Heisenberg
  • 4,787
  • 9
  • 47
  • 76
  • Are you just wanting it to display nicely? Take a look at `pd.options.display.float_format`. The above is expected behaviour for floats (see http://stackoverflow.com/questions/2100490/floating-point-inaccuracy-examples) – AChampion Sep 07 '16 at 01:11
  • thank you for reply I would like to handle huge size number, like budget calculation. I met some trouble about this kind of calcuclation... So I want to calculate precisely. by using this option, Can I avoid this trouble? – Heisenberg Sep 07 '16 at 01:17

2 Answers2

2

Many rational numbers can't be represented exactly as a floating-point number. In particular, any number that has to have a five as a factor in the denominator, like 1/(2*5), can't be represented exactly. There isn't much you can do about this: either round the displayed number so it looks right, or use an infinite-precision library or a rational-numbers library. Here's a basic way to round the displayed number:

>>> print "%.20f" % 0.1
0.10000000000000000555
>>> print "%.4f" % 0.1
0.1000

D-Von
  • 416
  • 2
  • 5
  • thank you. I would like to calculate billion like number, for example 1billion * 0.1%. can I get correct result ? – Heisenberg Sep 07 '16 at 01:23
  • 1
    Not necessarily. In this case, you do, because the result (one million) is an integer that is well within the range of representable integers. In other cases, you will get a result that is very, very close to the right answer but not exactly right. If you really need exact results, you should read up on topics like numerical analysis, the IEEE 754 floating-point standard, and the Python decimal library (which gives exact results at a cost in memory and time and code complexity). But chances are, you can afford to be off by a penny here and there, then round the result at display time. – D-Von Sep 07 '16 at 01:31
1

As a folow-up to the suggestion by @D-Von, the following python packages can be useful to you: decimal and fractions

Then you can do some things like:

from fractions import Fraction
from decimal import Decimal
f = Fraction(1, 10)
d = Decimal('0.1')
f = f/100
d = d/100
str(d)

And all the time you are not working with floats but with rational numbers. See the documentation for more examples.

Ramon Crehuet
  • 3,679
  • 1
  • 22
  • 37