【问题标题】:How to select an unlike number in an array in C++?如何在 C++ 中的数组中选择不同的数字?
【发布时间】:2009-07-31 00:15:55
【问题描述】:

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

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 ​​个点。

【问题讨论】:

  • 为您的任务严格定义dissimilar
  • 这些数字代表什么?错误来源是什么?有关分发的任何信息。如果您可以添加这些信息,将更容易回答。
  • 离群值是您要查找的术语。
  • 异常值消除是他标题问题的解决方案,但不是他的实际问题。他的实际问题是背景识别之一......

标签: c++ average


【解决方案1】:

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

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

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

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

【讨论】:

  • 我在后面的分析中使用了 TSpectrum;今天早些时候想探索它对波形的用途。好建议。信号来自滨松 PMT 和 kludge 基地。使用LabVIEW -> 输出波形到文本通过泰克示波器进行数据采集。在传输文本文件后使用 ROOT 进行分析。 ROOT 脚本创建脉冲面积和脉冲高度的历史记录。 10,000 个波形捕获(2000 个样本点)大约需要一个小时。分析只有几分钟的时间,所以我有空闲时间,我只是不耐烦。 j
  • 是的,我知道 2.7 个波形/秒是一个缓慢的 DAQ。 =) 我的设置有很多缺陷,但它完成了工作。
  • 不是我有经验的硬件链。仍然:如果垂直刻度以伏特为单位,则峰值非常小。您能否获得更多收益(最好使用更多 HV,但即使在范围内也可能有效)。
  • 我正在研究脉搏谱;我需要获得小脉冲和大脉冲,因此范围设置为不排除任何一个......但是小脉冲的分辨率很糟糕。不能使用外部放大,因为它是对 PMT 的增益研究。
【解决方案2】:

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

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

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

【讨论】:

  • 排序不是一个坏主意,如果我对这些值进行直方图,我可以很容易地拟合高斯峰值,其平均值将是我所追求的地面值,但可能过于复杂.
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      任何具有统计意义的方法和接近它的好方法(Dark Eru,Daniel White)都将过于计算密集而无法重复,我想我已经找到了一种解决方法,可以让以后更正(意思是,离开它没有接地)。

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

      【讨论】:

      • 介意告诉我们您打算使用的方法吗?
      【解决方案6】:

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

      算法是 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
      

      【讨论】:

        猜你喜欢
        • 2013-06-20
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 2011-05-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多