difference between np.inf and float('Inf')
Question:
Is there some difference between NumPy np.inf
and float('Inf')
?
float('Inf') == np.inf
returns True
, so it seems they are interchangeable, thus I was wondering why NumPy has defined its own “inf” constant, and when should I use one constant instead of the other (considering style concerns too)?
Answers:
TL, DR: There is no difference and they can be used interchangeably.
Besides having the same value as math.inf
and float('inf')
:
>>> import math
>>> import numpy as np
>>> np.inf == float('inf')
True
>>> np.inf == math.inf
True
It also has the same type:
>>> import numpy as np
>>> type(np.inf)
float
>>> type(np.inf) is type(float('inf'))
float
That’s interesting because NumPy also has it’s own floating point types:
>>> np.float32(np.inf)
inf
>>> type(np.float32(np.inf))
numpy.float32
>>> np.float32('inf') == np.inf # nevertheless equal
True
So it has the same value and the same type as math.inf
and float('inf')
which means it’s interchangeable.
Reasons for using np.inf
- It’s less to type:
np.inf
(6 chars)
math.inf
(8 chars; new in python 3.5)
float('inf')
(12 chars)
That means if you already have NumPy imported you can save yourself 6 (or 2) chars per occurrence compared to float('inf')
(or math.inf
).
- Because it’s easier to remember.
At least for me, it’s far easier to remember np.inf
than that I need to call float
with a string.
Also, NumPy defines some additional aliases for infinity:
np.Inf
np.inf
np.infty
np.Infinity
np.PINF
It also defines an alias for negative infinity:
np.NINF
Similarly for nan
:
np.nan
np.NaN
np.NAN
- Constants are constants
This point is based on CPython and could be completely different in another Python implementation.
A float
CPython instance requires 24 Bytes:
>>> import sys
>>> sys.getsizeof(np.inf)
24
If you can re-use the same instance you might save a lot of memory compared to creating lots of new instances. Of course, this point is mute if you create your own inf
constant but if you don’t then:
a = [np.inf for _ in range(1000000)]
b = [float('inf') for _ in range(1000000)]
b
would use 24 * 1000000 Bytes (~23 MB) more memory than a
.
-
Accessing a constant is faster than creating the variable.
%timeit np.inf
37.9 ns ± 0.692 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
%timeit float('inf')
232 ns ± 13.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit [np.inf for _ in range(10000)]
552 µs ± 15.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit [float('inf') for _ in range(10000)]
2.59 ms ± 78.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Of course, you can create your own constant to counter that point. But why bother if NumPy already did that for you.
Is there some difference between NumPy np.inf
and float('Inf')
?
float('Inf') == np.inf
returns True
, so it seems they are interchangeable, thus I was wondering why NumPy has defined its own “inf” constant, and when should I use one constant instead of the other (considering style concerns too)?
TL, DR: There is no difference and they can be used interchangeably.
Besides having the same value as math.inf
and float('inf')
:
>>> import math
>>> import numpy as np
>>> np.inf == float('inf')
True
>>> np.inf == math.inf
True
It also has the same type:
>>> import numpy as np
>>> type(np.inf)
float
>>> type(np.inf) is type(float('inf'))
float
That’s interesting because NumPy also has it’s own floating point types:
>>> np.float32(np.inf)
inf
>>> type(np.float32(np.inf))
numpy.float32
>>> np.float32('inf') == np.inf # nevertheless equal
True
So it has the same value and the same type as math.inf
and float('inf')
which means it’s interchangeable.
Reasons for using np.inf
- It’s less to type:
np.inf
(6 chars)math.inf
(8 chars; new in python 3.5)float('inf')
(12 chars)
That means if you already have NumPy imported you can save yourself 6 (or 2) chars per occurrence compared to float('inf')
(or math.inf
).
- Because it’s easier to remember.
At least for me, it’s far easier to remember np.inf
than that I need to call float
with a string.
Also, NumPy defines some additional aliases for infinity:
np.Inf
np.inf
np.infty
np.Infinity
np.PINF
It also defines an alias for negative infinity:
np.NINF
Similarly for nan
:
np.nan
np.NaN
np.NAN
- Constants are constants
This point is based on CPython and could be completely different in another Python implementation.
A float
CPython instance requires 24 Bytes:
>>> import sys
>>> sys.getsizeof(np.inf)
24
If you can re-use the same instance you might save a lot of memory compared to creating lots of new instances. Of course, this point is mute if you create your own inf
constant but if you don’t then:
a = [np.inf for _ in range(1000000)]
b = [float('inf') for _ in range(1000000)]
b
would use 24 * 1000000 Bytes (~23 MB) more memory than a
.
-
Accessing a constant is faster than creating the variable.
%timeit np.inf 37.9 ns ± 0.692 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) %timeit float('inf') 232 ns ± 13.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) %timeit [np.inf for _ in range(10000)] 552 µs ± 15.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) %timeit [float('inf') for _ in range(10000)] 2.59 ms ± 78.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Of course, you can create your own constant to counter that point. But why bother if NumPy already did that for you.