2009-07-31 37 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的值,然後很容易找到中位數/近似平均值/刪除異常值等。如果您可以承受損失數據中的某些精度,然後維護排序列表(如果這適合您的數據),那麼這將是我的首選選項。

相關問題