为什么scipy中的norm.cdf比norm.pdf快?

问题描述 投票:0回答:1

我现在使用的是 scipy 对于 norm.pdfnorm.cdf 计算。我想知道为什么 cdf 快于 pdf?

我知道有一些渐近的方法,用于处理? 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
python scipy statistics normal-distribution
1个回答
0
投票

看了一下源码,发现 scipy.stats.norm.pdf 只需返回 x 使用NumPy对pdf进行计算。

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

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

对于cdf,由于我们讲的是正态分布,所以使用了特殊的函数(对于它们和正态分布之间的关系。见此).

SciPy实现了特殊的功能 直接在C. 特别是,累积分布函数的计算方法为: 1.ndtr.c. 所以,即使NumPy真的很快,在这种情况下,我想C还是更快。

EDIT

对不起,我才发现我的回答并没有完全回答你的问题。

首先,NumPy也是在C语言中实现数学运算的,因此,要理解为什么会出现时间上的差异,就应该了解C语言中发生了什么。

  • 如果你看一下这个 疑问,看来数值和硬件结构会影响时间。

于是我又检查了一下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到底是如何处理指数的信息,无法得到比较。

© www.soinside.com 2019 - 2024. All rights reserved.