我意识到np.power(a, b)
慢于np.exp(b * np.log(a))
:
import numpy as np
a, b = np.random.random((2, 100000))
%timeit np.power(a, b) # best of 3: 4.16 ms per loop
%timeit np.exp(b * np.log(a)) # best of 3: 1.74 ms per loop
结果相同(具有1e-16阶的几个数值误差)。
np.power
还做了哪些其他工作?此外,我如何自己找到这些问题的答案?
答案 0 :(得分:33)
Under the hood这两个表达式都调用相应的C函数pow
或exp
和log
以及running a profiling on those in C++,而没有任何numpy代码,给出:
pow : 286 ms
exp(log) : 93 ms
这与numpy时间一致。因此,似乎主要区别在于C函数pow
比exp(log)
慢。
为什么呢?似乎共振的一部分是表达式对于所有输入都不相等。例如,如果a
为b
,power
为exp(log)
,则>>> np.power(-2, 2)
4
>>> np.exp(2 * np.log(-2))
nan
会失败:
0 ** 0
另一个例子是>>> np.power(0, 0)
1
>>> np.exp(0 * np.log(0))
nan
:
exp(log)
因此,power
技巧仅适用于输入子集,而power
适用于所有(有效)输入。
除此之外,exp(log)
保证根据IEEE 754 standard提供完全精确度,而dplyr
可能会出现舍入错误。