【问题标题】:How to calculate the standard deviation from a histogram? (Python, Matplotlib)如何计算直方图的标准差? (Python,Matplotlib)
【发布时间】:2018-06-10 18:14:14
【问题描述】:

假设我有一个数据集并使用 matplotlib 绘制所述数据集的直方图。

n, bins, patches = plt.hist(data, normed=1)

如何使用hist() 返回的nbins 值计算标准差?我目前正在这样做以计算平均值:

s = 0
for i in range(len(n)):
   s += n[i] * ((bins[i] + bins[i+1]) / 2) 
mean = s / numpy.sum(n)

这似乎工作正常,因为我得到了非常准确的结果。但是,如果我尝试像这样计算标准偏差:

t = 0
for i in range(len(n)):
  t += (bins[i] - mean)**2
std = np.sqrt(t / numpy.sum(n))

我的结果与numpy.std(data) 返回的结果相差甚远。用每个 bin 的中心点替换左侧 bin 限制也不会改变这一点。我觉得问题在于 nbins 值实际上并不包含关于各个数据点如何在每个 bin 中分布的任何信息,但我的分配工作明确要求我使用它们来计算标准偏差。

【问题讨论】:

  • 我可以访问它,但作业明确指出我不应该使用原始数据。我认为整个措辞(“这些值对于计算分布的平均值、方差或其他属性非常有用。”)让我感到困惑,因为它没有提到任何关于结果只是近似值的内容。 :)

标签: python-3.x numpy matplotlib


【解决方案1】:

您尚未使用 n[i] 对每个 bin 的贡献进行加权。将t的增量改为

    t += n[i]*(bins[i] - mean)**2

顺便说一句,您可以通过使用 numpy.averageweights 参数来简化(并加快)计算。

这是一个例子。首先,生成一些数据来处理。在计算直方图之前,我们将计算输入的样本均值、方差和标准差。

In [54]: x = np.random.normal(loc=10, scale=2, size=1000)

In [55]: x.mean()
Out[55]: 9.9760798903061847

In [56]: x.var()
Out[56]: 3.7673459904902025

In [57]: x.std()
Out[57]: 1.9409652213499866

我将使用numpy.histogram 来计算直方图:

In [58]: n, bins = np.histogram(x)

mids 是 bin 的中点;它的长度与n 相同:

In [59]: mids = 0.5*(bins[1:] + bins[:-1])

均值的估计是mids的加权平均值:

In [60]: mean = np.average(mids, weights=n)

In [61]: mean
Out[61]: 9.9763028267760312

在这种情况下,它非常接近原始数据的平均值。

估计方差是与均值的平方差的加权平均值:

In [62]: var = np.average((mids - mean)**2, weights=n)

In [63]: var
Out[63]: 3.8715035807387328

In [64]: np.sqrt(var)
Out[64]: 1.9676136767004677

该估计值在实际样本标准偏差的 2% 以内。

【讨论】:

  • 谢谢,完全忘记了!但是,我的结果仍然有点不准确(类似于 0.19 与 numpy 的 0.17)。我是否正确地假设您只能从直方图获得标准偏差的近似值,还是我还缺少其他东西?
  • 没错,您不能期望使用直方图计算的值与使用完整数据集计算的值匹配。直方图会丢失信息。
【解决方案2】:

以下答案等同于Warren Weckesser's,但对于那些喜欢将均值作为期望值的人来说可能更熟悉:

counts, bins = np.histogram(x)
mids = 0.5*(bins[1:] + bins[:-1])
probs = counts / np.sum(counts)

mean = np.sum(probs * mids)  
sd = np.sqrt(np.sum(probs * (mids - mean)**2))

请注意,在某些情况下,您可能需要无偏样本方差,其中权重不是由 N 归一化而是由 N-1 归一化。

【讨论】:

    猜你喜欢
    • 2020-01-28
    • 1970-01-01
    • 2020-03-09
    • 2022-01-23
    • 1970-01-01
    • 2016-02-07
    • 2019-02-15
    • 2020-02-28
    • 1970-01-01
    相关资源
    最近更新 更多