周期数据直方图的统计

时间:2012-04-22 15:14:50

标签: python numpy statistics complex-numbers

对于(-pi,pi)范围内的一系列角度值,我制作直方图。有没有一种有效的方法来计算均值和模态(可能后)值?请考虑以下示例:

import numpy as N, cmath
deg = N.pi/180.
d = N.array([-175., 170, 175, 179, -179])*deg
i = N.sum(N.exp(1j*d))
ave = cmath.phase(i)
i /= float(d.size)
stdev = -2. * N.log(N.sqrt(i.real**2 + i.imag**2))

print ave/deg, stdev/deg

现在,让我们有一个直方图:

counts, bins = N.histogram(data, N.linspace(-N.pi, N.pi, 360))

是否可以计算平均值,具有计数和分档的模式?对于非周期性数据,平均值的计算很简单:

ave = sum(counts*bins[:-1])

模态值的计算需要更多努力。实际上,我不确定下面的代码是否正确:首先,我确定最常发生的垃圾箱,然后计算算术平均值:

cmax = bins[N.argmax(counts)]
mode = N.mean(N.take(bins, N.nonzero(counts == cmax)[0]))

我不知道如何计算这些数据的标准偏差。对我所有问题(至少上述那些问题)的一个明显的解决方案是将直方图数据转换为数据系列,然后在计算中使用它。然而,这并不优雅,效率低下。

任何提示都将非常感激。


这是我写的部分解决方案。

import numpy as N, cmath
import scipy.stats as ST

d = [-175, 170.2, 175.57, 179, -179, 170.2, 175.57, 170.2]
deg = N.pi/180.
data = N.array(d)*deg

i = N.sum(N.exp(1j*data))
ave = cmath.phase(i)  # correct and exact mean for periodic data
wrong_ave = N.mean(d)

i /= float(data.size)
stdev = -2. * N.log(N.sqrt(i.real**2 + i.imag**2))
wrong_stdev = N.std(d)

bins = N.linspace(-N.pi, N.pi, 360)
counts, bins = N.histogram(data, bins, normed=False)
# consider it weighted vector addition
nz = N.nonzero(counts)[0]
weight = counts[nz]
i = N.sum(weight * N.exp(1j*bins[nz])/len(nz))
pave = cmath.phase(i)  # correct and approximated mean for periodic data
i /= sum(weight)/float(len(nz))
pstdev = -2. * N.log(N.sqrt(i.real**2 + i.imag**2))
print
print 'scipy: %12.3f (mean) %12.3f (stdev)' % (ST.circmean(data)/deg, \
                                               ST.circstd(data)/deg)

运行时会产生以下结果:

 mean:      175.840       85.843      175.360
stdev:        0.472      151.785        0.430

scipy:      175.840 (mean)        3.673 (stdev)

现在有几条评论:第一列给出了均值/ stdev的计算结果。可以看出,平均值与scipy.stats.circmean一致(感谢JoeKington指出它)。不幸的是,stdev不同。我稍后再看。第二列给出了完全错误的结果(来自numpy的非周期性均值/标准显然在这里不起作用)。第3列给出了我想从直方图数据中获取(@JoeKington:我的原始数据不适合我的计算机内存..,@ dmytro:感谢您的输入:当然,bin大小会影响结果但是在我的应用程序我没有太多选择,即我必须以某种方式减少数据)。可以看出,正确计算平均值(第3列),stdev需要进一步关注:)

2 个答案:

答案 0 :(得分:5)

查看scipy.stats.circmeanscipy.stats.circstd

或者你只有直方图计数,而不是" raw"数据?如果是这样,你可以在直方图计数上加Von Mises distribution并以这种方式逼近均值和stddev。

答案 1 :(得分:1)

以下是如何获得近似值。

Var(x) = <x^2> - <x>^2以来,我们有:

meanX = N.sum(counts * bins[:-1]) / N.sum(counts)
meanX2 = N.sum(counts * bins[:-1]**2) / N.sum(counts)
std = N.sqrt(meanX2 - meanX**2)
相关问题