首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么norm.cdf在枕骨上比norm.pdf更快?

为什么norm.cdf在枕骨上比norm.pdf更快?
EN

Stack Overflow用户
提问于 2020-05-25 03:30:04
回答 1查看 1.2K关注 0票数 2

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

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

下面是一些简单的示例:

代码语言:javascript
运行
复制
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)

以下是运行结果:

代码语言:javascript
运行
复制
0:00:05.736985
0:00:04.896390
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-25 10:01:49

快速查看源代码显示,scipy.stats.norm.pdf只是使用NumPy返回pdf的x值:

代码语言:javascript
运行
复制
def _norm_pdf(x):
return np.exp(-x**2/2.0) / _norm_pdf_C

在哪里_norm_pdf_C = np.sqrt(2*np.pi)

对于正态分布,由于我们讨论正态分布,所以使用了特殊的函数(对于它们与正态分布,请看这里之间的关系)。

SciPy实现了特殊的函数直接在C中。特别是,累积分布函数是由ndtr.c计算的。所以,即使NumPy非常快,在这种情况下C仍然更快,我想。

编辑

对不起,我刚刚意识到我的回答并没有完全回答你的问题。

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

  • 如果您查看这个问题,数字值和硬件架构似乎会影响时间。

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

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

代码语言:javascript
运行
复制
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()

这段代码给了我:

代码语言:javascript
运行
复制
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再次变得更快。其原因可以是用多项式逼近来计算精度。但是我没有找到关于C是如何处理指数来得到比较的信息。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61995309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档