1

我正在使用 C++ 为某些任务编写 ROOT 脚本。在某些时候,我有一系列双打,其中许多非常相似,而一两个不同。我想平均除那些拇指酸痛之外的所有数字。我应该如何处理它?例如,让我们考虑:

x = [2.3, 2.4, 2.11, 10.5, 1.9, 2.2, 11.2, 2.1]

我想以某种方式平均除10.5和之外11.2的所有数字,不同的数字。该算法将重复数千次,并且双精度数组有 2000 个条目,因此需要优化(同时保持可读性)。谢谢!

查看: http ://tinypic.com/r/111p0ya/3 脉冲 y 值的“不同”数字。

此点用于确定波形的接地值。我正在将最负值与地面进行比较,并希望获得一种更好的接地方法,而不是平均样本中的前 N ​​个点。

4

6 回答 6

1

鉴于您使用的是 ROOT,您可能会考虑查看TSpectrum支持从未指定数量的峰下提取背景的类......

我从来没有使用过这么多基线噪音的它们,但它们应该很健壮。

顺便说一句:这些数据的来源是什么。峰值看起来像一个粒子探测器脉冲,但高水平的背景抖动表明您可以通过对 DAQ 硬件进行一些相当小的调整来真正改善事情,这可能比尝试解决一个困难的软件问题更好。

最后,除非你被限制在一些非常原始的硬件上(在这种情况下你为什么以及如何运行 ROOT?),如果你只有几千个这样的光谱,你可以负担一个相当慢的算法。还是每个事件有 2000 个光谱和高事件率?

于 2009-07-31T01:44:39.023 回答
1

如果可以,请维护一个排序列表;然后,您可以在每次计算平均值时轻松地切掉列表的头部和尾部。

这很像根据中值删除异常值(即,您将需要两次遍历数据,一次找到中值 - 这几乎与排序浮点数据一样慢,另一次计算平均值) ,但在以维护排序列表为代价计算平均值时需要较少的开销。哪个最快将完全取决于您的情况。当然,你真正想要的可能是中位数!

如果您有离散数据(例如,字节 = 256 个可能的值),您可以使用 256 个直方图“箱”,对您的数据进行一次遍历,计算每个箱中的值,然后很容易找到中位数/近似值平均值/删除异常值等。如果您可以承受失去数据中的某些精度的损失,这将是我的首选选项,然后维护一个排序列表(如果这适合您的数据)。

于 2009-07-31T07:18:29.303 回答
0

一种快速的方法可能是取中位数,然后取离中位数不远的数字平均值。

“不远,”依赖于你的项目。

于 2009-07-31T00:23:39.303 回答
0

确定可能的异常值的一个好的经验法则是计算四分位数范围 (IQR),然后任何距离最近四分位数 1.5*IQR 的值都是异常值。

这是许多统计系统(如 R)用于自动检测异常值的基本方法。

于 2009-07-31T00:26:47.090 回答
0

任何具有统计意义的方法和接近它的好方法(Dark Eru,Daniel White)的计算量都太大而无法重复,我想我已经找到了一种解决方法,可以让以后更正(意思是,不要-接地)。

感谢您的建议。如果我有时间,我会调查他们并想看看他们的收益是否值得放慢速度。

于 2009-07-31T00:40:56.953 回答
0

这是我以前使用过的一种快速而肮脏的方法(如果一开始异常值很少,并且您没有非常复杂的条件来判断异常值的构成,则效果很好)

算法是 O(N)。唯一真正昂贵的部分是部门。

这里真正的优势是您可以在几分钟内启动并运行它。

avgX = Array[0]  // initialize array with the first point
N = length(Array)
percentDeviation = 0.3  // percent deviation acceptable for non-outliers
count = 1
foreach x in Array[1..N-1]
    if      x < avgX + avgX*percentDeviation
       and  x > avgX - avgX*percentDeviation
          count++
          sumX =+ x
          avgX = sumX / count
    endif
endfor

return avgX
于 2009-07-31T00:53:50.850 回答