2009-07-31 97 views
1

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

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

我想以某种方式平均所有除10.511.2,在不同的人的号码。该算法将重复执行数千次,双精度数组有2000个条目,因此需要优化(同时保持可读性)。谢谢!

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

确定波形接地值的要点。我将最负值与地面进行比较,希望得到更好的接地方法,而不是平均样本中前N个点。

+1

为您的任务给出'不相似'的严格定义。 – 2009-07-31 00:18:49

+0

这些数字代表什么?什么是错误来源?任何关于分配的信息。如果你可以添加这些信息,它会更容易回答。 – 2009-07-31 00:25:03

+0

异常值是您正在寻找的术语。 – Eric 2009-07-31 07:21:24

回答

1

假设你正在使用ROOT你可能会考虑寻找具有从峰数目不详下提取的背景支持TSpectrum类...

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

BTW:这个数据的来源是什么。峰值看起来像是一个粒子探测器脉冲,但高水平的背景抖动表明,通过对数据采集硬件进行一些相当小的调整,您确实可以改进某些事情,这可能比试图解决困难的软件问题更好。最后,除非你仅限于一些非常原始的硬件(在这种情况下你为什么以及如何运行ROOT?),如果你只有几千个这样的光谱,你可以买得起一个非常慢的算法。或者是每个事件2000个光谱和一个高事件率?

0

快速的方法可能是取中位数,然后取平均数与中位数的距离不远。

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

0

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

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

0

任何具有统计显着性的方法(Dark Eru,Daniel White)的计算强度都不会重复,而且我认为我找到了一个可以稍后纠正的方法(意思是说,让它不接地)。

感谢您的建议。如果我有时间,我会研究它们,并且想看看它们的收益是否值得放缓。

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 
1

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

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

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

相关问题