Javascript 数字数据分组和异常值去除
Javascript number data grouping and outlier removal
我有一个数组如下:
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]
200
和 800
将作为异常值删除,[80, 90, 100]
将是第一组,[280, 281, 287]
将是第二组,[500, 510, 520]
作为第三个
我已经编写了用于移除外部异常值的代码,使用第一和第三四分位数非常简单。换句话说,将 800
作为离群值从 mySecondArray
中移除是没有问题的。但它不会删除 280
作为异常值。
我想异常值可以定义为成员少于 n
的组,所以真正的问题是 将这些数据划分为适当数量的有效方法是什么组数?
非常感谢任何帮助!
这只是一个简单的实现,它可能不是这组问题的完美解决方案,但对于您的示例来说应该足够了 - 它可能还不止于此。
通过查看数字之间的平均距离,并将该距离与每个数字两边的距离进行比较,应该可以去除异常值。因此接下来,可以使用相同的指标进行分组。
function Sum(arr){
return arr.filter(i => !isNaN(i)).reduce((p,c) => p+c,0);
};
function Avg(arr){
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));
我有一个数组如下:
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]
200
和 800
将作为异常值删除,[80, 90, 100]
将是第一组,[280, 281, 287]
将是第二组,[500, 510, 520]
作为第三个
我已经编写了用于移除外部异常值的代码,使用第一和第三四分位数非常简单。换句话说,将 800
作为离群值从 mySecondArray
中移除是没有问题的。但它不会删除 280
作为异常值。
我想异常值可以定义为成员少于 n
的组,所以真正的问题是 将这些数据划分为适当数量的有效方法是什么组数?
非常感谢任何帮助!
这只是一个简单的实现,它可能不是这组问题的完美解决方案,但对于您的示例来说应该足够了 - 它可能还不止于此。
通过查看数字之间的平均距离,并将该距离与每个数字两边的距离进行比较,应该可以去除异常值。因此接下来,可以使用相同的指标进行分组。
function Sum(arr){
return arr.filter(i => !isNaN(i)).reduce((p,c) => p+c,0);
};
function Avg(arr){
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));