【问题标题】:pylab.hist(data, normed=1). Normalization seems to work incorrectpylab.hist(数据,规范=1)。规范化似乎工作不正确
【发布时间】:2011-07-26 18:17:29
【问题描述】:

我正在尝试使用参数 normed=1 创建直方图

例如:

import pylab

data = ([1,1,2,3,3,3,3,3,4,5.1])    
pylab.hist(data, normed=1)
pylab.show()

我预计 bin 的总和为 1。但是,其中一个 bin 比 1 大。这个标准化做了什么?以及如何创建一个直方图的归一化使得直方图的积分等于 1?

【问题讨论】:

  • 也可以试试pylab.hist(data, bins=5, range=(1, 6), normed=1)。这将导致 bin 宽度为 1。
  • "bin 的总和为 1。但是,其中一个 bin 大于 1" -> 这并不矛盾!

标签: python graph numpy matplotlib


【解决方案1】:

请参阅我的另一篇文章,了解如何使直方图中所有 bin 的总和等于 1: https://stackoverflow.com/a/16399202/1542814

复制和粘贴:

weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights=weights)

myarray 包含您的数据的位置

【讨论】:

  • 如果你在做频率直方图,这是最好的方法!
  • 仅供参考,如果您使用上述方法,请务必保留normed=0。
  • 与this example 中的格式化程序完美结合使用(使用normed 代替权重;权重的工作原理与bin 大小无关,而normed/density 需要大小统一的bin,来自documentation)。
  • 太棒了!最好的方式
【解决方案2】:

根据documentation normed:如果为 True,则结果是 bin 处的概率密度函数的值,归一化使得范围内的积分为 1。请注意,直方图值的总和将不等于 1,除非选择了统一宽度的 bin;它不是概率质量函数。这是来自 numpy doc,但对于 pylab 应该是相同的。

In []: data= array([1,1,2,3,3,3,3,3,4,5.1])
In []: counts, bins= histogram(data, normed= True)
In []: counts
Out[]: array([ 0.488,  0.,  0.244,  0.,  1.22,  0.,  0.,  0.244,  0.,  0.244])
In []: sum(counts* diff(bins))
Out[]: 0.99999999999999989

所以简单的标准化是根据以下文档完成的:

In []: counts, bins= histogram(data, normed= False)
In []: counts
Out[]: array([2, 0, 1, 0, 5, 0, 0, 1, 0, 1])
In []: counts_n= counts/ sum(counts* diff(bins))
In []: counts_n
Out[]: array([ 0.488,  0.,  0.244,  0.,  1.22 ,  0.,  0.,  0.244,  0.,  0.244])

【讨论】:

  • @smirnoffs:你认为它不能大于 1 的理由是什么?谢谢
  • @eat 归一化直方图,据我所知,是一个概率密度函数。概率不能超过 1。
  • @smirnoffs:你能提供一些链接来备份你对标准化直方图的定义吗? FWIW 从文档中可以看出标准化是如何工作的。 counts* diff(bins) 为您提供所需的内容。谢谢
  • 概率 densities 可以是任何非负数,只要该范围内的 integral(不是总和)等于 1。跨度>
  • 这个答案是指numpy.histogram,而不是pylab.hist
【解决方案3】:

我认为您将垃圾箱高度与垃圾箱内容混淆了。您需要添加每个 bin 的内容,即所有 bin 的 height*width。那应该 = 1。

【讨论】:

  • 所以为了澄清大家,你会在 OP 的直方图上放置什么作为 y 轴标签?
【解决方案4】:

这个标准化做了什么?

为了规范化序列,您必须考虑 bin 大小。 根据documentation,bin 的默认数量为 10。因此,bin 大小为(data.max() - data.min() )/10,即 0.41。 如果是normed=1,那么条形的高度就是这样的总和,乘以 0.41,得到 1。这就是积分时发生的情况。

以及如何创建一个直方图的归一化使得直方图的积分等于 1?

我认为您希望直方图的总和(而不是其积分)等于 1。在这种情况下,最快的方法似乎是:

h = plt.hist(data)
norm = sum(data)
h2 = [i/norm for i in h[0]]
plt.bar(h[1],h2)

【讨论】:

    【解决方案5】:

    我遇到了同样的问题,在解决它的同时又出现了另一个问题:如何将归一化的 bin 频率绘制为百分比,并在 rounded 值上加上刻度。我在这里发布它以防它对任何人有用。在我的示例中,我选择 10% (0.1) 作为 y 轴的最大值,并选择 10 个步骤(一个从 0% 到 1%,一个从 1% 到 2%,依此类推)。诀窍是在 data 计数处设置刻度(这是plt.hist 的输出列表n),接下来将使用FuncFormatter 类将其转换为百分比。这是我所做的:

    import matplotlib.pyplot as plt
    from matplotlib.ticker import FuncFormatter
    
    fig, ax = plt.subplots()
    
    # The required parameters
    num_steps = 10
    max_percentage = 0.1
    num_bins = 40
    
    # Calculating the maximum value on the y axis and the yticks
    max_val = max_percentage * len(data)
    step_size = max_val / num_steps
    yticks = [ x * step_size for x in range(0, num_steps+1) ]
    ax.set_yticks( yticks )
    plt.ylim(0, max_val)
    
    # Running the histogram method
    n, bins, patches = plt.hist(data, num_bins)
    
    # To plot correct percentages in the y axis     
    to_percentage = lambda y, pos: str(round( ( y / float(len(data)) ) * 100.0, 2)) + '%'
    plt.gca().yaxis.set_major_formatter(FuncFormatter(to_percentage))
    
    plt.show()
    

    地块

    标准化之前:y 轴单位是 x 轴上 bin 间隔内的样本数:

    标准化后:y 轴单位是 bin 值的频率,作为所有样本的百分比

    【讨论】:

      【解决方案6】:

      还有numpy.histogram。如果设置density=True,输出会被归一化。

      normed : bool, optional

      由于令人困惑/错误的行为,该关键字在 Numpy 1.6 中已弃用。它将在 Numpy 2.0 中删除。请改用密度关键字。如果为 False,则结果将包含每个 bin 中的样本数。如果为 True,则结果是 bin 处的概率密度函数的值,归一化以使范围内的积分为 1。改用密度。

      density : bool, optional

      如果为 False,则结果将包含每个 bin 中的样本数。如果为 True,则结果是 bin 处的概率密度函数值,经过归一化处理,使得范围内的积分为 1。请注意,除非选择了统一宽度的 bin,否则直方图值的总和将不等于 1;它不是概率质量函数。如果给定,则覆盖 normed 关键字。

      【讨论】:

        【解决方案7】:

        你的期望是错误的

        垃圾箱高度的总和乘以它的宽度等于一。或者,正如您所说的正确,integral 必须是一个,不是您要集成的功能。

        是这样的:概率(如“人在 20 到 40 岁之间的概率是……%”)是积分(“从 20 到 40 岁” ) 在概率密度上。 bins 高度显示概率密度,而宽度乘以高度显示某个点在此 bin 中的概率(您将常数假设函数、bin 的高度、从 bin 的开头到 bin 的结尾积分)。高度本身就是密度,不是概率。这是一个每个宽度的概率,当然可以高于一个。

        简单示例:想象一个从 0 到 1 的概率密度函数,其值为 0 从 0 到 0.9。函数可能在 0.9 和 1 之间?如果您整合它,请尝试一下。它会高于 1。

        顺便说一句:根据粗略的猜测,您的 hist 的高度乘以宽度的总和似乎大约为 1,不是吗?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-07-23
          • 1970-01-01
          • 2018-01-02
          • 2010-12-29
          • 2022-09-28
          • 2012-05-22
          • 2013-12-11
          相关资源
          最近更新 更多