【问题标题】:Statistics of histogram created from weighted data - numpy从加权数据创建的直方图统计 - numpy
【发布时间】:2017-06-26 00:49:08
【问题描述】:

我有 2 个数据数组,其中一个描述我要绘制的数据,第二个描述该数据的频率或权重。

我使用创建直方图

import numpy as np
import matplotlib.pyplot as plt

data = [7., 8.2, 9.6, 11.3, 13.2, 15.5, 18.1, 21.2, 24.9, 29.1, 34.1, 40.0]
freq = [2., 4.1, 4.5, 3.2, 2.7, 2.1, 1.3, 1., 0.9, 0., 0., 0.]

h = np.histogram(data, weights = freq, bins = data)
f = plt.hist(data, weights = freq, bins = data)

我现在想找到结果直方图的均值、标准差、偏度和峰度,但由于数据是“加权”或预先计算的,我似乎无法让 scipy.stats.describe 函数工作。有什么想法吗?

我应该说清楚,我已经尝试过 scipy.stats.describe 但似乎无法找到允许我做我想做的事情的重量参数。我真的不知道有什么工具可以帮助解决这个问题,而且谷歌搜索并没有返回很多有用的结果(尽管我承认我可能在搜索错误的东西)。

为了使事情变得更复杂,您的鹰眼会注意到数据均匀分布在日志空间中,而不是真实空间中。因此,如果您的方法涉及高斯拟合,您可能需要牢记这一点...

【问题讨论】:

  • “因此,如果您的方法涉及高斯拟合,您可能需要牢记这一点……” ... 我们正在评分吗?
  • 我只是指出,如果有人想返回一种拟合数据的方法,那么数据在日志空间中是隔开的,这会影响拟合。无需刻薄。
  • 通常预计提问者会在请求贡献之前提供他们尝试过的某种形式......不过我同意你的观点,刻薄永远不会帮助任何人!
  • 对不起,我应该更清楚一点,我试图找到一种使用 scipy.stats.describe 工具的方法,却发现它缺少我需要指定数据的参数以正确的方式。也就是说,它的功能完全符合预期,我只是不想使用它应该如何使用它!我现在把它说得更清楚。
  • 问题似乎是“如何从直方图中计算统计矩?”。在这种情况下,最好放在Cross Validated

标签: python numpy matplotlib scipy statistics


【解决方案1】:

问题非常简单,您可以在这里编写自己的函数,而不需要 scipy.stats 中的函数。基本上你在这里给出的是分布函数,并且想要计算期望值。这是由一个简单的积分给出的。解决方案的一个例子是

def integrator(f,data,freq):
    diffs = np.roll(data,-1)-data
    return (f(data[:-1])*freq[:-1]*diffs[:-1]).sum()

freq_norm = freq/integrator(lambda x:1,data,freq)

exp_x = integrator(lambda x:x,data,freq_norm)
exp_x2 = integrator(lambda x:x**2,data,freq_norm)
exp_x4 = integrator(lambda x:x**4,data,freq_norm)

mean = exp_x
kurt = integrator(lambda x: ((x-exp_x)/std)**4,data,freq_norm)
skew = integrator(lambda x: ((x-exp_x)/std)**3,data,freq_norm)

【讨论】:

  • 这看起来不错。羞耻它没有包含在某个地方,但这就是我想要的。只是想检查一下,kurt 应该是那个还是超过 (exp_x2 - exp_x**2)**2?如果我想要偏度,我是否只需将 exp_x3 添加到列表中并重复此操作?
  • 我的例子中的峰度是错误的。您可以使用积分器(lambda x: ((x-exp_x)/std)**4,data,freq_norm) 来计算它。通过将指数从 4 更改为 3,可以使用相同的表达式计算偏度。
  • @AlexHoward 你们两个确定这是正确的吗?如果您的 freq 是(直到标准化)密度,则使用间隔宽度缩放是正确的。如果它们是 bin 计数,则不是。
  • 老实说,完全不确定。它们是 bin 计数,而不是密度。
  • @PaulPanzer 你是完全正确的。我假设密度。如果它们是 bin 计数,则应使用宽度移除缩放。
【解决方案2】:

您可以使用 scipy.stats.rv_histogram 生成一个随机变量,其分布由 numpy.histogram 的输出给出,然后对其使用 stats 方法得到您想要的。

import numpy as np
import scipy.stats as stats

data = [7., 8.2, 9.6, 11.3, 13.2, 15.5, 18.1, 21.2, 24.9, 29.1, 34.1, 40.0]
freq = [2., 4.1, 4.5, 3.2, 2.7, 2.1, 1.3, 1., 0.9, 0., 0., 0.]

rv = stats.rv_histogram(np.histogram(data, weights=freq))

您也可以使用rv.moments(n) 直接获取(非中心)时刻,其中n 是您感兴趣的顺序。 均值, var, skew, kurt = rv.stats(moments='mvsk')

我希望这可能对某人有所帮助!

【讨论】:

    猜你喜欢
    • 2013-11-19
    • 1970-01-01
    • 2018-04-16
    • 2015-01-25
    • 2020-12-16
    • 2012-05-03
    • 2020-09-12
    • 1970-01-01
    • 2020-04-11
    相关资源
    最近更新 更多