假设我有一个数据集,并使用matplotlib绘制了该数据集的直方图。
n, bins, patches = plt.hist(data, normed=1)
如何使用hist()
返回的n
和bins
值计算标准差?我现在这样做是为了计算平均值:
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限制也不会改变这一点。我感觉问题在于n
和bins
值实际上并不包含任何关于各个数据点在每个bin中如何分布的信息,但我正在处理的赋值明确要求我使用它们来计算标准差。
发布于 2018-06-11 02:30:06
您还没有使用n[i]
对每个bin的贡献进行加权。将t
的增量更改为
t += n[i]*(bins[i] - mean)**2
顺便说一句,您可以通过使用带有weights
参数的numpy.average
来简化(和加速)计算。
下面是一个例子。首先,生成一些要处理的数据。在计算直方图之前,我们将计算输入的样本均值、方差和标准差。
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
是柱状图的中点;它的长度与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%以内。
发布于 2019-08-08 02:24:28
下面的答案等同于Warren Weckesser's,但对于那些更喜欢将mean作为期望值的人来说,可能更熟悉:
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进行归一化的。
https://stackoverflow.com/questions/50786699
复制相似问题