在Python中给出mean,std给出正态分布的概率

时间:2012-09-13 18:53:35

标签: python statistics scipy probability

如何在Python中给出mean,std给出正态分布的概率?我总是可以根据像这个问题中的OP那样的定义明确地编写我自己的函数:Calculating Probability of a Random Variable in a Distribution in Python

只是想知道是否有库函数调用将允许您这样做。在我的想象中它会这样:

nd = NormalDistribution(mu=100, std=12)
p = nd.prob(98)

Perl中有一个类似的问题:How can I compute the probability at a point given a normal distribution in Perl?。但我没有在Python中看到一个。

Numpy有一个random.normal函数,但它就像是抽样,而不是我想要的。

9 个答案:

答案 0 :(得分:97)

scipy.stats中有一个:

>>> import scipy.stats
>>> scipy.stats.norm(0, 1)
<scipy.stats.distributions.rv_frozen object at 0x928352c>
>>> scipy.stats.norm(0, 1).pdf(0)
0.3989422804014327
>>> scipy.stats.norm(0, 1).cdf(0)
0.5
>>> scipy.stats.norm(100, 12)
<scipy.stats.distributions.rv_frozen object at 0x928352c>
>>> scipy.stats.norm(100, 12).pdf(98)
0.032786643008494994
>>> scipy.stats.norm(100, 12).cdf(98)
0.43381616738909634
>>> scipy.stats.norm(100, 12).cdf(100)
0.5

[要注意的一件事 - 只是提示 - 是参数传递有点宽泛。由于代码的设置方式,如果您不小心写了scipy.stats.norm(mean=100, std=12)而不是scipy.stats.norm(100, 12)scipy.stats.norm(loc=100, scale=12),那么它会接受它,但会默默地丢弃这些额外的关键字参数,给你默认值(0,1)。]

答案 1 :(得分:30)

Scipy.stats是一个很棒的模块。只是提供另一种方法,您可以使用

直接计算
import math
def normpdf(x, mean, sd):
    var = float(sd)**2
    denom = (2*math.pi*var)**.5
    num = math.exp(-(float(x)-float(mean))**2/(2*var))
    return num/denom

这使用此处的公式:http://en.wikipedia.org/wiki/Normal_distribution#Probability_density_function

进行测试:

>>> normpdf(7,5,5)  
0.07365402806066466
>>> norm(5,5).pdf(7)
0.073654028060664664

答案 2 :(得分:10)

这是more info。 首先,您正在处理冻结分布(在这种情况下冻结意味着其参数设置为特定值)。要创建冻结分布:

import scipy.stats
scipy.stats.norm(loc=100, scale=12)
#where loc is the mean and scale is the std dev
#if you wish to pull out a random number from your distribution
scipy.stats.norm.rvs(loc=100, scale=12)

#To find the probability that the variable has a value LESS than or equal
#let's say 113, you'd use CDF cumulative Density Function
scipy.stats.norm.cdf(113,100,12)
Output: 0.86066975255037792
#or 86.07% probability

#To find the probability that the variable has a value GREATER than or
#equal to let's say 125, you'd use SF Survival Function 
scipy.stats.norm.sf(125,100,12)
Output: 0.018610425189886332
#or 1.86%

#To find the variate for which the probability is given, let's say the 
#value which needed to provide a 98% probability, you'd use the 
#PPF Percent Point Function
scipy.stats.norm.ppf(.98,100,12)
Output: 124.64498692758187

答案 3 :(得分:3)

Python 3.8开始,标准库提供NormalDist对象作为statistics模块的一部分。

它可以用于获取 概率密度函数 pdf-随机样本X接近给定值x的可能性)给定平均值mu)和标准偏差sigma):

from statistics import NormalDist

NormalDist(mu=100, sigma=12).pdf(98)
# 0.032786643008494994

还要注意,NormalDist对象还提供了 累积分布函数 cdf-随机样本X小于或等于x):

NormalDist(mu=100, sigma=12).cdf(98)
# 0.43381616738909634

答案 4 :(得分:2)

请注意,概率概率密度 pdf() 不同,前面的一些答案参考了后者。 概率是变量具有特定值的机会,而概率密度是变量接近特定值的机会,这意味着某个范围内的概率。因此,要获得概率,您需要计算给定区间内概率密度函数的积分。作为一种近似值,您可以简单地将概率密度乘以您感兴趣的区间,从而得出实际概率。

import numpy as np
from scipy.stats import norm

data_start = -10
data_end = 10
data_points = 21
data = np.linspace(data_start, data_end, data_points)

point_of_interest = 5
mu = np.mean(data)
sigma = np.std(data)                                   
interval = (data_end - data_start) / (data_points - 1)
probability = norm.pdf(point_of_interest, loc=mu, scale=sigma) * interval

上面的代码将给出变量在 -10 到 10 之间的正态分布中具有 21 个数据点(意味着间隔为 1)的精确值 5 的概率。您可以使用固定的间隔值,具体取决于您想要达到的结果。

答案 5 :(得分:1)

答案中提到的维基百科引用的公式不能用于计算正常概率。您必须使用该公式编写数值积分近似函数,以便计算概率。

该公式计算概率密度函数的值。由于正态分布是连续的,因此必须计算积分以获得概率。维基百科网站提到了CDF,它没有正式发布的封闭形式。

答案 6 :(得分:1)

我写了这个程序来为你做数学运算。只需输入摘要统计信息即可。无需提供数组:

One-Sample Z-Test for a Population Proportion:

要为平均值而不是比例执行此操作,请相应地更改z的公式

答案 7 :(得分:0)

您可以使用内置于数学库的错误函数,如website所述。

答案 8 :(得分:0)

如果您想找到x mean = 1的2个值之间的区域;标准偏差= 2; x在[0.5,2]

之间的概率
import scipy.stats
scipy.stats.norm(1, 2).cdf(2) - scipy.stats.norm(1,2).cdf(0.5)