2016-08-23 48 views
1

我有一個數組如下:的Javascript數數據分組和異常值去除

var myArray = [3, 6, 8, 9, 16, 17, 19, 37]

我需要去除異常值以及組中的剩餘數據到任何出現的獨特的基團。在這種情況下,37將作爲異常值被刪除,[3, 6, 8, 9]將被返回,因爲第一組和[16, 17, 19]將作爲第二組返回。

這裏是第二示例

var mySecondArray = [80, 90, 100, 200, 280, 281, 287, 500, 510, 520, 800]

200800將作爲異常值除去,[80, 90, 100]將是在第一組,[280, 281, 287]將是第二和[500, 510, 520]作爲第三。

我已經編寫了代碼,用於刪除外部外部這是足夠簡單的使用第一和第三四分位數。換句話說,從mySecondArray中刪除800作爲異常值是沒有問題的。但它不會刪除280作爲異常值。

我想,一個局外人然後可以定義爲一組具有小於n成員,因此真正的問題是什麼是這個數據劃分成組適當數量的一種有效的方法?

任何幫助非常感謝!

+0

你可能尋找[K-means聚類(https://en.wikipedia.org/wiki/K-means_clustering) –

+0

所以你'n ==可10 「這裏? – Redu

+0

不,如果'n'是10,那麼在我的例子中,所有東西都是異常的:)在我的例子中,'n'可能是3。換句話說,2個或更少項目的組是異常值。 – abagshaw

回答

1

jsFiddle Demo

這只是一個簡單的實現,也未必是這一系列問題的完美解決方案,但它應該能滿足您的例子 - 它可能工作超過這一點。

通過查看您的數字之間的平均距離,並將該距離與每個數字兩邊的距離進行比較,應該可以刪除異常值。因此,可以使用相同的度量來進行分組。

function Sum(arr){ 
 
\t return arr.filter(i => !isNaN(i)).reduce((p,c) => p+c,0); 
 
}; 
 
function Avg(arr){ 
 
\t return Sum(arr)/arr.length; 
 
} 
 
function groupby(arr,dist){ 
 
    var groups = []; 
 
    var group = []; 
 
    for(var i = 0; i < arr.length; i++){ 
 
    group.push(arr[i]); 
 
    if(arr[i+1] == undefined)continue; 
 
    if(arr[i+1] - arr[i] > dist){ 
 
     groups.push(group); 
 
     group = []; 
 
    } 
 
    } 
 
    groups.push(group); 
 
    return groups; 
 
} 
 
function groupOutlier(arr){ 
 
    var distbefore = arr.map((c,i,a) => i == 0 ? undefined : c - a[i-1]); 
 
    var distafter = arr.map((c,i,a) => i == a.length-1 ? undefined : a[i+1] - c); 
 

 
    var avgdist = Avg(distafter); 
 

 
    var result = arr.filter((c,i,a) => !(distbefore[i] == undefined ? distafter[i] > avgdist : (distafter[i] == undefined ? distbefore[i] > avgdist : distbefore[i] > avgdist && distafter[i] > avgdist))); 
 
    
 
    return groupby(result,avgdist); 
 
} 
 

 
var myArray = [3, 6, 8, 9, 16, 17, 19, 37]; 
 

 
console.log(groupOutlier(myArray)); 
 

 
var mySecondArray = [80, 90, 100, 200, 280, 281, 287, 500, 510, 520, 800] 
 

 
console.log(groupOutlier(mySecondArray));