如何在Python中从正态分布计算百分位数?

8

问题陈述 - 随机变量X服从N(25, 4)。找到X的以下百分位数:

a. 第10个百分位数

b. 第90个百分位数

c. 第80个百分位数

d. 第50个百分位数

尝试1

我的代码:

import numpy as np
import math
import scipy.stats
mu=25
sigma=4
a=mu-(1.282*4)
b=mu+(1.282*4)

我从Z分数表中获取了这些值。

尝试2

X=np.random.normal(25,4,10000) # sample size not mentioned in 
                                 problem. I just assumed it
a_9 = np.percentile(X,10)
b_9 = np.percentile(X,90)
c_9 = np.percentile(X,80)
d_9 = np.percentile(X,50)

但是根据练习平台的隐藏测试用例,这些答案是不正确的。有人能告诉我正确计算答案的方法吗?是否有任何scipy.stats函数可用于此?


为什么第二次尝试是错误的?你有一些测试用例它无法通过吗? - David
是的,我的答案与测试用例的预定义隐藏答案不匹配。 - MVKXXX
正如我在评论中提到的,我假设样本大小为10000,但问题中没有给出。也许这是个问题……我不知道......是否有其他方法来解决这个问题陈述? - MVKXXX
1
在尝试 2 中,您正在使用随机数据填充 X,因此每次执行的百分位都会有所不同。Z-分数不是固定值,而是计算 z = (x - mu) / sigma,因此使用随机数据填充 x 永远不会产生相同的结果。由于您拥有此数据集的 Z 分数,因此可以根据您的第一个示例计算百分位数 mu+(z*sigma) - RJ Adriaansen
3个回答

13

您可以使用scipy.stats和内置的ppf函数(请查看documentation)。

import numpy as np
import scipy.stats as sps
import matplotlib.pyplot as plt

mu = 25
sigma = 4

# define the normal distribution and PDF
dist = sps.norm(loc=mu, scale=sigma)
x = np.linspace(dist.ppf(.001), dist.ppf(.999))
y = dist.pdf(x)

# calculate PPFs
ppfs = {}
for ppf in [.1, .5, .8, .9]:
    p = dist.ppf(ppf)
    ppfs.update({ppf*100: p})

# plot results
fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(x, y, color='k')
for i, ppf in enumerate(ppfs):
    ax.axvline(ppfs[ppf], color=f'C{i}', label=f'{ppf:.0f}th: {ppfs[ppf]:.1f}')
ax.legend()
plt.show()

提供了 enter image description here

6

使用scipy.stats.norm(正态分布)中的ppf方法。

scipy.stats.norm.ppf(0.1, loc=25, scale=4)

这个函数类似于r语言中的qnorm函数。ppf方法可以计算给定百分位数时随机变量的值。


这很酷,要获取所有百分位数,您可以执行以下操作: scipy.stats.norm.ppf([0.1, 0.9, 0.8, 0.5], loc=25, scale=4) 得到 [19.87379374, 30.12620626, 28.36648493, 25.]。 第100个百分位数为 inf,不是来自统计背景,不确定原因。 - Prox

-1
a_9 = 19.88
b_9 = 30.12
c_9 = 28.36
d_9 = 25.00

X = np.random.normal(25,4,10000000)

请您能否详细说明一下? - Tejas Shetty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接