我正在使用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个点。

有帮助吗?

解决方案

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

我从未使用过如此多的基线噪音,但它们应该很强大。

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

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

其他提示

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

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

如果您有离散数据(例如,字节= 256个可能的值),您可以使用256个直方图'bins',只需对数据进行一次传递,计算每个bin中的值,然后很容易找到中位数/近似均值/删除异常值等。如果你能负担得失一些数据的精确度,然后维护一个排序列表,如果这适合你的数据,这将是我的首选方案。

快速的方法可能是采用中位数,然后取出与中位数相差不多的平均数。

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

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

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

任何具有统计意义的方法和接近它的好方法(Dark Eru,Daniel White)计算过于强烈,不能重复,我想我已经找到了一个可以让以后纠正的工作(意思是,离开没有根据)。

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

这是我之前使用的一种快速而肮脏的方法(如果开头只有非常少的异常值,那么效果很好,而且对于异常值的构成没有非常复杂的条件)

算法是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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top