概率密度函数 numpy 直方图/ scipy 统计学

4
我们有一个数组a=range(10)。使用numpy.histogram函数:
hist,bins=numpy.histogram(a,bins=(np.max(a)-np.min(a))/1, range=np.min(a),np.max(a)),density=True)

根据numpy教程: 如果density=True,结果是在bin中的概率密度函数值,归一化后该范围内的积分为1。 结果是:
array([ 0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.2])

我尝试使用scipy.stats来完成同样的操作:
mean = np.mean(a)
sigma = np.std(a)
norm.pdf(a, mean, sigma)

然而,结果是不同的:
array([ 0.04070852,  0.06610774,  0.09509936,  0.12118842,  0.13680528,0.13680528,  0.12118842,  0.09509936,  0.06610774,  0.04070852])

我想知道为什么。

更新:我想提出一个更一般的问题。我们如何在不使用numpy.histogram的情况下获得数组的概率密度函数,以实现density=True

3个回答

2
如果density=True,结果是该bin中概率密度函数的值,已经归一化,使其在范围内的积分为1。这里的“已归一化”并不意味着它将使用正态分布进行转换,它仅仅是每个bin中的每个值都会被总条目数除以,以使得总密度等于1。

根据您的说法,如果我将bins=(np.max(a)-np.min(a))/1更改为(np.max(a)-np.min(a))/2,则sum(hist)也将为1。但是,如果您这样做,您会发现它并不是这样。 - DimKoim
@DimKoim,你说得对。我刚意识到对于numpy.histogram(density=True),它并不像那样工作。我不确定为什么,但很可能需要确保箱子的宽度为1。然而,归一化的基本概念是,如果你绘制密度图,你想要获得曲线下面积的值为1。请参阅此链接以更好地了解归一化和numpy.histogram的问题:https://dev59.com/KmEi5IYBdhLWcg3wMZ3a - jtitusj
1
问题在于当我不想要一个bin=1时。事实上,更一般的问题是如何计算数组的概率密度函数。 - DimKoim
1
我明白了。在这种情况下,不要使用density=True,而是使用hist, bins = numpy.histogram(*args) then hist = hist.astype(float)/sum(hist)。这将确保满足概率密度函数的条件。 - jtitusj
谢谢,但我仍在尝试一种不使用numpy.histogram的方法来获取数组的pdf。 - DimKoim
还有其他人提供意见吗? - DimKoim

1

您不能将numpy.histogram()scipy.stats.norm()进行比较,原因如下:

scipy.stats.norm()是一个正态分布的连续随机变量,而numpy.histogram()处理的是序列(不连续


如果您使用scipy.stats.rv_continuous.pdf,那么您将得到正确的结果。您能给我一个例子吗? - DimKoim

1
从直方图绘制连续概率函数(PDF) - Python解决。详细说明请参考此博客。(http://howdoudoittheeasiestway.blogspot.com/2017/09/plotting-continuous-probability.html)否则,您可以使用以下代码。
n, bins, patches = plt.hist(A, 40, histtype='bar')
plt.show()
n = n/len(A)
n = np.append(n, 0)
mu = np.mean(n)
sigma = np.std(n)
plt.bar(bins,n, width=(bins[len(bins)-1]-bins[0])/40)
y1= (1/(sigma*np.sqrt(2*np.pi))*np.exp(-(bins - mu)**2 /(2*sigma**2)))*0.03
plt.plot(bins, y1, 'r--', linewidth=2)
plt.show()

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