Python Matplotlib:如何将直方图转换为离散概率质量函数?

Python Matplotlib:如何将直方图转换为离散概率质量函数?,python,matplotlib,probability,histogram,Python,Matplotlib,Probability,Histogram,关于matplotlib的hist()函数,我有一个问题 我正在编写一个代码来绘制数据的柱状图,其值从0到1不等。例如: values = [0.21, 0.51, 0.41, 0.21, 0.81, 0.99] bins = np.arange(0, 1.1, 0.1) a, b, c = plt.hist(values, bins=bins, normed=0) plt.show() 上面的代码生成了一个正确的直方图(我无法发布图像,因为我没有足够的声誉)。就频率而言,它看起来像: [0

关于matplotlib的hist()函数,我有一个问题

我正在编写一个代码来绘制数据的柱状图,其值从0到1不等。例如:

values = [0.21, 0.51, 0.41, 0.21, 0.81, 0.99]

bins = np.arange(0, 1.1, 0.1)
a, b, c = plt.hist(values, bins=bins, normed=0)
plt.show()
上面的代码生成了一个正确的直方图(我无法发布图像,因为我没有足够的声誉)。就频率而言,它看起来像:

[0 0 2 0 1 1 0 0 1 1]
我想将此输出转换为离散概率质量函数,即对于上述示例,我想得到以下频率值:

[ 0.  0.  0.333333333  0.  0.166666667  0.166666667  0.  0.  0.166666667  0.166666667 ] # each item in the previous array divided by 6)
我想我只需要将hist()函数中的参数更改为'normed=1'。但是,我得到以下直方图频率:

[ 0.  0.  3.33333333  0.  1.66666667  1.66666667  0.  0.  1.66666667  1.66666667 ]
这不是我所期望的,我不知道如何得到离散概率质量函数,它的和应该是1.0。在下面的链接()中提出了类似的问题,但我认为问题没有得到解决


我提前感谢您的帮助。

原因是
norm=True
给出了正确的答案。在概率论中,连续随机变量的概率密度函数或密度描述了该随机变量取给定值的相对可能性

让我们考虑一个非常简单的例子。

x=np.arange(0.1,1.1,0.1)
array([ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])

# Bin size
bins = np.arange(0.05, 1.15, 0.1)
np.histogram(x,bins=bins,normed=1)[0]
[ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.]
np.histogram(x,bins=bins,normed=0)[0]/float(len(x))
[ 0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1,  0.1]

# Change the bin size
bins = np.arange(0.05, 1.15, 0.2)
np.histogram(x,bins=bins,normed=1)[0]
[ 1.,  1.,  1.,  1.,  1.]
np.histogram(x,bins=bins,normed=0)[0]/float(len(x))
[ 0.2,  0.2,  0.2,  0.2,  0.2]
如上所述,您可以看到,x位于
[0.05-0.15]
[0.15-0.25]
之间的概率为
1/10
,而如果将箱子大小更改为
0.2
,则其位于
[0.05-0.25]
[0.25-0.45]
之间的概率为
1/5
。现在,这些实际概率值取决于料仓大小,然而,概率密度与料仓大小无关。因此,这是执行上述操作的唯一正确方法,否则需要在每个绘图中说明箱子宽度


因此,在你的例子中,如果你真的想在每个箱子上绘制概率值(而不是概率密度),那么你可以简单地将每个直方图的频率除以总元素的数量。但是,我建议您不要这样做,除非您使用的是离散变量,并且每个BIN都表示该变量的一个可能值

从直方图绘制连续概率函数(PDF)——用Python解决。有关详细说明,请参阅此。() 否则,您可以使用下面的代码

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()

你确定你没有在输出的末尾漏掉一个“e-2”吗?事实上,链接中给出的答案(和评论)是正确的:直方图上的积分等于1。在您的示例中,取每个条的值,乘以条的宽度,然后将它们相加。你会发现它是1(去掉0:10/3*0.1+5/3*0.1+5/3*0.1+5/3*0.1+5/3*0.1+5/3*0.1=30/3*0.1=1的条)。基本的numpy例程就是这样工作的。您可能需要使用numpy.histogram和条形图来获得所需内容。嗨,Drew,不,我刚刚复制了plt.hist(…)的输出。所以应该是这样的。但是谢谢你的评论!嗨,埃弗特,嗯,我明白了。我想知道numpy为什么这么做。鉴于指定了垃圾箱的宽度(0.1),我希望它能自动进行您提到的计算:|非常感谢您的评论!你好,imsc,我意识到我没有提交我的评论。谢谢,你的回答很有帮助!