python - 为什么scipy中norm.cdf比norm.pdf更快?

标签 python scipy statistics normal-distribution

我现在使用 scipy 进行一些 norm.pdfnorm.cdf 计算。我想知道为什么 cdfpdf 更快?

我知道norm.cdf有一些渐近方法,而在scipy中似乎集成了norm.pdf用来。这就是为什么我无法想象 cdf 比 pdf 更快。如果集成的话,cdf应该比pdf慢很多(也许并行计算能有很大帮助?);如果应用渐近方法,我仍然认为 cdf 可能比 pdf 慢一点。

下面显示了一些简单的示例:

import scipy.stats as st
from datetime import datetime
import numpy as np
num_iter = 100000
x_lower = 0.25
x_upper = 0.75

time_start = datetime.now()
for x in np.arange(x_lower, x_upper, (x_upper - x_lower) / (num_iter - 1)):
    y = st.norm.pdf(x)
time_end = datetime.now()
print(time_end - time_start)

time_start = datetime.now()
for x in np.arange(x_lower, x_upper, (x_upper - x_lower) / (num_iter - 1)):
    y = st.norm.cdf(x)
time_end = datetime.now()
print(time_end - time_start)

以下是运行结果:

0:00:05.736985
0:00:04.896390

最佳答案

快速浏览一下源代码就会发现,scipy.stats.norm.pdf 只是使用 NumPy 返回 pdf 的 x 值:

def _norm_pdf(x):
return np.exp(-x**2/2.0) / _norm_pdf_C

其中_norm_pdf_C = np.sqrt(2*np.pi)

对于 cdf,由于我们讨论的是正态分布,因此使用了特殊函数(对于它们与正态分布之间的关系, see here )。

SciPy实现特殊函数directly in C 。特别是,累积分布函数是根据 ndtr.c 计算得出的。 。因此,即使 NumPy 确实很快,我认为在这种情况下 C 仍然更快。

编辑

抱歉,我刚刚意识到我的回答并没有完全回答您的问题。

首先,NumPy 也在 C 中实现了数学运算。 因此,要理解为什么时代不同,就应该了解 C 中发生了什么。

  • 如果你看看这个question ,看来数值和硬件架构都会影响时间。

所以我再次检查了 cdf 的 C 实现,我发现评估特殊函数的多项式的常量和系数不是计算出来的,而是存储在数组和变量中!例如,1/sqrt(2) 包含在 NPY_SQRT1_2 中。这可能就是 cdf 比 pdf 更快的原因!

因此我尝试计算已初始化常量的 pdf:

import scipy.stats as st
from datetime import datetime
import numpy as np
num_iter = 100000
x_lower = 0.25
x_upper = 0.75

const = np.sqrt(2*np.pi)
time_start = datetime.now()
for x in np.arange(x_lower, x_upper, (x_upper - x_lower) / (num_iter - 1)):
    # y = st.norm.pdf(x)
    y = np.exp((x**2 / 2)) / const
time_end = datetime.now()
print(time_end - time_start)

time_start = datetime.now()
for x in np.arange(x_lower, x_upper, (x_upper - x_lower) / (num_iter - 1)):
    y = st.norm.cdf(x)
time_end = datetime.now()

这段代码给了我:

0:00:00.202531
0:00:07.703083

请注意,norm.pdf 还预先初始化了 pdf 的分母,但在 for 循环中,您每次都会调用该方法,从而减慢速度。

P.S.:如果您尝试摆脱原始代码中的循环并简单地使用 x = np.arange(x_lower, x_upper, (x_upper - x_lower)/(num_iter - 1)) ,cdf 又更快了。原因可能是 cdf 是用多项式近似计算的。但我没有找到关于 C 到底如何处理指数来进行比较的信息。

关于python - 为什么scipy中norm.cdf比norm.pdf更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61995309/

相关文章:

python - 我如何比较 Django 中的日期?

python - 在 Python 中连接字符串和整数

python - scipy给出了 undefined symbol : clapack_sgesv

python - scipy.ndimage.filters.convolve 和 scipy.signal.convolve 有什么区别?

statistics - Octave mann-whitney/u_test p 值混淆

statistics - 计算 p 的极值的广义均值

python - 如何使用取模运算符在两个常量之间绑定(bind)一个数字?

python - OpenCV BGR 和 PyPlot RGB

python - 定义cython类内部函数的参数和cython中的快速积分计算

c - CUDA代码的数据收集部分意外输出“0”