在 Python 中分别测试正无穷大或负无穷大
Testing for positive infinity, or negative infinity, individually in Python
math.isinf() 对正无穷大或负无穷大的测试集中在一起。什么是 pythonic 方式来明确地测试它们?
检验正无穷大的方法:
x == float('+inf')
math.isinf(x) and x > 0
测试负无穷大的方法:
x == float('-inf')
math.isinf(x) and x < 0
反汇编方式一:
>>> def ispinf1(x): return x == float("inf")
...
>>> dis.dis(ispinf1)
1 0 LOAD_FAST 0 (x)
3 LOAD_GLOBAL 0 (float)
6 LOAD_CONST 1 ('inf')
9 CALL_FUNCTION 1
12 COMPARE_OP 2 (==)
15 RETURN_VALUE
反汇编方式二:
>>> def ispinf2(x): return isinf(x) and x > 0
...
>>> dis.dis(ispinfs)
1 0 LOAD_GLOBAL 0 (isinf)
3 LOAD_FAST 0 (x)
6 CALL_FUNCTION 1
9 JUMP_IF_FALSE_OR_POP 21
12 LOAD_FAST 0 (x)
15 LOAD_CONST 1 (0)
18 COMPARE_OP 4 (>)
>> 21 RETURN_VALUE
This answer 除了 x>0 之外似乎更倾向于方法 2。
"pythonic" 方法是选择可读和可维护的内容。
也就是说,x == float("inf")
和 x == float("-inf")
对我来说可读性稍强一些,我更喜欢它们。 math.isinf(x) and x > 0
更快,但每次调用只需要大约 40 纳秒 。
因此,除非您要检查大量数字,否则 运行 时间不会有太大差异。
还有numpy
>>> import numpy as np
>>> np.isneginf([np.inf, 0, -np.inf])
array([False, False, True], dtype=bool)
>>> np.isposinf([np.inf, 0, -np.inf])
array([ True, False, False], dtype=bool)
然后就是一般isinf
>>> np.isinf([np.inf, 0, -np.inf])
array([ True, False, True], dtype=bool)
这里有一些jupyterlab
计时测试,看看什么是最快的方法(从最慢到最快排序):
准备:
import math
import numpy as np
n = 100000000
a = list(range(n))
a.extend([np.inf, float('inf'), math.inf])
结果:
%%time
def inf_to_none(x):
if np.isinf(x):
return None
else:
return x
r = list(map(inf_to_none, a))
>> CPU times: user 1min 30s, sys: 481 ms, total: 1min 31s
Wall time: 1min 31s
%%time
def inf_to_none(x):
if x == float('inf'):
return None
else:
return x
r = list(map(inf_to_none, a))
>> CPU times: user 19.6 s, sys: 494 ms, total: 20.1 s
Wall time: 20.2 s
%%time
def inf_to_none(x):
if math.isinf(x):
return None
else:
return x
r = list(map(inf_to_none_math, a))
>> CPU times: user 15 s, sys: 292 ms, total: 15.3 s
Wall time: 15.3 s
%%time
d = {np.inf: None}
l = lambda x: d.get(x,x)
r = list(map(l, a))
>> CPU times: user 11.7 s, sys: 256 ms, total: 12 s
Wall time: 12 s
%%time
def inf_to_none(x):
if x == np.inf:
return None
else:
return x
r = list(map(inf_to_none, a))
>> CPU times: user 11.2 s, sys: 280 ms, total: 11.5 s
Wall time: 11.5 s
%%time
def inf_to_none(x):
if x == math.inf:
return None
else:
return x
r = list(map(inf_to_none, a))
>> CPU times: user 11 s, sys: 276 ms, total: 11.3 s
Wall time: 11.3 s
我认为这些结果很有趣,为了缩短使用==
比较。
math.isinf() 对正无穷大或负无穷大的测试集中在一起。什么是 pythonic 方式来明确地测试它们?
检验正无穷大的方法:
x == float('+inf')
math.isinf(x) and x > 0
测试负无穷大的方法:
x == float('-inf')
math.isinf(x) and x < 0
反汇编方式一:
>>> def ispinf1(x): return x == float("inf")
...
>>> dis.dis(ispinf1)
1 0 LOAD_FAST 0 (x)
3 LOAD_GLOBAL 0 (float)
6 LOAD_CONST 1 ('inf')
9 CALL_FUNCTION 1
12 COMPARE_OP 2 (==)
15 RETURN_VALUE
反汇编方式二:
>>> def ispinf2(x): return isinf(x) and x > 0
...
>>> dis.dis(ispinfs)
1 0 LOAD_GLOBAL 0 (isinf)
3 LOAD_FAST 0 (x)
6 CALL_FUNCTION 1
9 JUMP_IF_FALSE_OR_POP 21
12 LOAD_FAST 0 (x)
15 LOAD_CONST 1 (0)
18 COMPARE_OP 4 (>)
>> 21 RETURN_VALUE
This answer 除了 x>0 之外似乎更倾向于方法 2。
"pythonic" 方法是选择可读和可维护的内容。
也就是说,x == float("inf")
和 x == float("-inf")
对我来说可读性稍强一些,我更喜欢它们。 math.isinf(x) and x > 0
更快,但每次调用只需要大约 40 纳秒 。
因此,除非您要检查大量数字,否则 运行 时间不会有太大差异。
还有numpy
>>> import numpy as np
>>> np.isneginf([np.inf, 0, -np.inf])
array([False, False, True], dtype=bool)
>>> np.isposinf([np.inf, 0, -np.inf])
array([ True, False, False], dtype=bool)
然后就是一般isinf
>>> np.isinf([np.inf, 0, -np.inf])
array([ True, False, True], dtype=bool)
这里有一些jupyterlab
计时测试,看看什么是最快的方法(从最慢到最快排序):
准备:
import math
import numpy as np
n = 100000000
a = list(range(n))
a.extend([np.inf, float('inf'), math.inf])
结果:
%%time
def inf_to_none(x):
if np.isinf(x):
return None
else:
return x
r = list(map(inf_to_none, a))
>> CPU times: user 1min 30s, sys: 481 ms, total: 1min 31s
Wall time: 1min 31s
%%time
def inf_to_none(x):
if x == float('inf'):
return None
else:
return x
r = list(map(inf_to_none, a))
>> CPU times: user 19.6 s, sys: 494 ms, total: 20.1 s
Wall time: 20.2 s
%%time
def inf_to_none(x):
if math.isinf(x):
return None
else:
return x
r = list(map(inf_to_none_math, a))
>> CPU times: user 15 s, sys: 292 ms, total: 15.3 s
Wall time: 15.3 s
%%time
d = {np.inf: None}
l = lambda x: d.get(x,x)
r = list(map(l, a))
>> CPU times: user 11.7 s, sys: 256 ms, total: 12 s
Wall time: 12 s
%%time
def inf_to_none(x):
if x == np.inf:
return None
else:
return x
r = list(map(inf_to_none, a))
>> CPU times: user 11.2 s, sys: 280 ms, total: 11.5 s
Wall time: 11.5 s
%%time
def inf_to_none(x):
if x == math.inf:
return None
else:
return x
r = list(map(inf_to_none, a))
>> CPU times: user 11 s, sys: 276 ms, total: 11.3 s
Wall time: 11.3 s
我认为这些结果很有趣,为了缩短使用==
比较。