Safest way to convert float to integer in python?
All integers that can be represented by floating point numbers have an exact representation. So you can safely use int
on the result. Inexact representations occur only if you are trying to represent a rational number with a denominator that is not a power of two.
That this works is not trivial at all! It's a property of the IEEE floating point representation that int∘floor = ⌊⋅⌋ if the magnitude of the numbers in question is small enough, but different representations are possible where int(floor(2.3)) might be 1.
To quote from Wikipedia,
Any integer with absolute value less than or equal to 224 can be exactly represented in the single precision format, and any integer with absolute value less than or equal to 253 can be exactly represented in the double precision format.
Which is the efficient way to convert a float into an int in python?
Test it with timeit
:
$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'int(n)'
10000000 loops, best of 3: 0.234 usec per loop
$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'n // 1'
10000000 loops, best of 3: 0.218 usec per loop
So floor division is only a faster by a small margin. Note that these values are very close, and I had to crank up the loop repeat count to iron out random influences on my machine. Even with such a high count, you need to repeat the experiments a few times to see how much the numbers still vary and what comes out faster most of the time.
This is logical, as int()
requires a global lookup and a function call (so state is pushed and popped):
>>> import dis
>>> def use_int(n):
... return int(n)
...
>>> def use_floordiv(n):
... return n // 1
...
>>> dis.dis(use_int)
2 0 LOAD_GLOBAL 0 (int)
3 LOAD_FAST 0 (n)
6 CALL_FUNCTION 1
9 RETURN_VALUE
>>> dis.dis(use_floordiv)
2 0 LOAD_FAST 0 (n)
3 LOAD_CONST 1 (1)
6 BINARY_FLOOR_DIVIDE
7 RETURN_VALUE
It is the LOAD_GLOBAL
and CALL_FUNCTION
opcodes that are slower than the LOAD_CONST
and BINARY_FLOOR_DIVIDE
opcodes; LOAD_CONST
is a simple array lookup, LOAD_GLOBAL
needs to do a dictionary lookup instead.
Binding int()
to a local name can make a small difference, giving it the edge again (as it has to do less work than // 1
floor division):
$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'int(n)'
10000000 loops, best of 3: 0.233 usec per loop
$ bin/python -mtimeit -n10000000 -s 'n = 1.345; int_=int' 'int_(n)'
10000000 loops, best of 3: 0.195 usec per loop
$ bin/python -mtimeit -n10000000 -s 'n = 1.345' 'n // 1'
10000000 loops, best of 3: 0.225 usec per loop
Again, you need to run this with 10 million loops to see the differences consistently.
That said, int(n)
is a lot more explicit and unless you are doing this in a time-critical loop, int(n)
wins it in readability over n // 1
. The timing differences are too small to make the cognitive cost of having to work out what // 1
does here worthwhile.
Is it possible to convert the result from float to integer in Python?
Python's builtin function does the job:
>>> print(int(seconds_to_hours(int(3600)))
1
>>> print(type(int(seconds_to_hours(int(3600))))
<class 'int'>
>>>
Note that your code hours=seconds/int(3600)
does not generate an integer, as opposed to C. If you want to do integer division, use double slash:
hours=seconds//int(3600)
# ^^
If you want to convert whatever into int
without knowing whether it can, use this function:
def try_int(v)
try:
return int(v)
except ValueError:
return v
Then you'll be able to convert only those that are able to be converted into int
into int
.
Convert a float to an integer that fits within a range
The 0 to 1 range can be thought as a percentage so you just need to multiply that number by the range length and add it to the lower bound of the range.
Example:
The float is 0.7, so it represents a 70%.
The range is 1 to 9 then the range length is 9 - 1 = 8.
8 * 0.7 = 5.6
1 is the lower limit of the range so we add 1 to the 5.6 = 6.6
If you truncate the result you get a 6, and if you round it evenly you get a 7.
You can test this by testing the limits:
For 0 => the result is 1
For 1 => the result is 9
Convert floats to ints in Pandas?
To modify the float output do this:
df= pd.DataFrame(range(5), columns=['a'])
df.a = df.a.astype(float)
df
Out[33]:
a
0 0.0000000
1 1.0000000
2 2.0000000
3 3.0000000
4 4.0000000
pd.options.display.float_format = '{:,.0f}'.format
df
Out[35]:
a
0 0
1 1
2 2
3 3
4 4
How do I parse a string to a float or int?
>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545
Python float to Decimal conversion
Python <2.7
"%.15g" % f
Or in Python 3.0:
format(f, ".15g")
Python 2.7+, 3.2+
Just pass the float to Decimal
constructor directly, like this:
from decimal import Decimal
Decimal(f)
Related Topics
Set Up Python Simplehttpserver on Windows
How to Sort a Pandas Dataframe by Index
Efficient Way to Remove Keys with Empty Strings from a Dict
Multithreaded Web Server in Python
Efficiently Updating Database Using SQLalchemy Orm
Can Pandas Plot a Histogram of Dates
How to Let a Raw_Input Repeat Until I Want to Quit
How to Find Which Columns Contain Any Nan Value in Pandas Dataframe
@Csrf_Exempt Does Not Work on Generic View Based Class
Rotate Image and Crop Out Black Borders
How to Read a Column of CSV as Dtype List Using Pandas
How to Add Default Parameters to Functions When Using Type Hinting
What Exactly Is the Point of Memoryview in Python
Default Filter in Django Admin