先決定偶數資料取哪一個中間值
中值濾波常用來減少孤立尖峰,但窗口是偶數時會有兩個中間值。有人取下面一個,有人取上面一個,也有人取兩者平均,三種結果都可能出現在軟體中。本篇先固定定義,再用數字逐步驗收,避免只寫中值兩字就以為雙方意思相同。
本篇標準數值中值採排序後兩個中間數的平均。四筆1、3、8、100已由小到大排列,中間是3與8,所以中值5.5。若規格選較低中值,結果是3;選較高中值則是8。三個名稱必須分清楚,不由輸出型別偷偷決定。
再看1、2、100、101,標準中值是(2+100)/2=51,並不是其中任何一筆實測值。這不是算法錯誤,而是偶數標準中值定義。如果用途要求輸出一定來自實測點,就要明確選低中值或高中值,並評估選擇造成的偏向。
對奇數窗口,排序後只有一個正中位置,例如五筆取第三筆。偶數取平均的問題雖消失,但缺樣、型別、排序和時間延遲仍然存在,不能因改成五筆就跳過其他驗收。
本文適用於一般數值訊號的離線分析和程式設計。來源引用Python統計函式是為對照數學定義,不代表PLC具有相同API。若用於快速控制或保護,需先確認濾波造成的延遲和尖峰抑制是否符合功能要求。
保留時間序列只排序副本
收到一個完整有效窗口後,先保留原始時間順序,再建立排序副本。假設到達順序100、1、8、3,排序後1、3、8、100,中值仍5.5。若直接把環形緩衝排序,下次可能無法正確移除最舊樣本,移動窗口也就被破壞。
保存樣本序號或時間戳,讓每個排序後數字仍能追到來源。相同值可能有不同時間,不需要為求中值刪除重複值。例如1、1、8、100,中間仍是1與8,結果4.5;去除重複後只剩三筆,中值8,已經是另一個資料集。
先檢查窗口筆數、單位與有效性。不同工程單位不能直接混排,無效碼也不能當成很大或很小的正常數字。若浮點資料含NaN,其比較行為可能使排序結果不符合直覺,應先依資料政策處理,不能假定它會自動排到最後。
本例要求完整四筆有效數據才計算;缺一筆時標窗口不完整。若另一個設計選擇丟掉無效值後計算,四筆就可能變三筆,中值定義與時間跨度也改了。要把有效筆數和採用政策一起輸出,不能表面仍顯示四點中值。
在PLC中還需檢查陣列上下界和排序執行成本。以零起算的四筆索引是0到3,中間位置1與2;以一起算則是2與3。先固定工程的索引約定,用四筆和五筆各測一次,避免差一格卻仍得到看似合理的數字。
兩個中間值平均時注意溢位與取整
標準中值5.5若目的欄位只能存整數,就必須另定捨入規則。最近且正好一半遠離零得到6;向零取整得到5;向負無窷取整也得到5。這些是中值之後的輸出政策,不能把取整後5當成原始中值就是5。
負數例用−100、−8、−3、−1,中間兩筆−8與−3,平均−5.5。最近且一半遠離零得到−6,向零是−5,向負無窮是−6。再用中間平均2.5區分最近偶數與一半遠離零:前者2、後者3。
兩中間值相加可能先溢位。若有號十六位元窗口四筆都是32767,正確中值仍32767,但32767+32767=65534已超出同型別上限。先在足夠寬型別中求和再除二,並確認整數除法是否會提前丟掉0.5。
單獨把結果變數設為寬型別不一定夠,因為加法可能已在窄型別中執行。實作需依平台確認運算前型別提升。不要用任意拆式來掩蓋問題;例如兩值先各整數除二再相加,奇數時就可能少一個單位。
驗收表同時列原窗口、排序結果、中間兩值、未捨入中值、輸出政策與最終整數。這樣結果5、6或−6不符時,可以指出是排序、位置選擇、溢位還是取整錯誤,不需要把所有問題都歸給濾波器。
尖峰能被壓住但連續污染會通過
用五筆窗口看孤立尖峰:10、10、10、10、100排序後第三筆是10,中值仍10。兩筆高值的10、10、10、100、100,中值也為10;但三筆高值的10、10、100、100、100,中值變100。這是本組資料的排序結果,不是所有雜訊都能去掉的保證。
如果三筆100是真正製程變化,中值終於改到100可能是合理反應;如果是連續干擾,它也會穿過濾波。算法本身不知道哪個才是真實訊號,需要對照原始資料、感測器和製程情境。不要用中值穩定當作量測正確的證明。
在固定100ms取樣、先前窗口全為10的條件下,新值連續改100,第三筆100進入五點窗口時,中值才變100。從第一筆新值到第三筆隔200ms。這只描述此步階案例,不代表中值濾波對所有波形都有固定群延遲。
失敗時先查是否破壞原始時間順序,再查窗口筆數和中間索引,最後查平均與取整。若只在大正數出錯,優先查加法溢位;若正數正常負數差一,查捨入;若斷線後忽然變零,查是否把缺值當零加入排序。
完成後應能重算5.5、51、負5.5及五點污染案例,並清楚顯示採標準、低或高中值。保留未捨入結果與原始窗口供查核,實際PLC排序負載和指令型別則需另測。
整數輸出的介面若不能容納半刻度,也可改用明示的固定小數點表示,例如用整數五十五搭配除數十來保存中值五點五。接收端必須一起知道倍率,不能把五十五直接當工程值。這是改變介面契約,需要同步更新顯示與資料記錄。
常見問題
問:1、3、8、100的中值一定是8嗎?答:標準中值是5.5,8是另外定義的高中值。
問:偶數中值不是實測點是否有錯?答:兩中間值平均可能不在原資料中,若要求實測點應另選低或高中值。
問:5.5放進整數欄位會怎樣?答:依明訂捨入規則,不能只寫轉整數而省略正負半刻度測試。
問:五點中值能擋所有尖峰嗎?答:不能,本例三筆高值占多數後中值會改為高值,仍需檢查原訊號。
參考:Python statistics官方文件,median、median_low與median_high定義及NaN注意事項;非PLC API。
參考:Python decimal官方文件,Rounding modes;作為明確捨入政策的定義參考。