在开发中会遇到一个List中的个别数据明显的脏数据,比如一组数据为[1,2,8,10,8,5,2,4,6,11,15,1,2,8,10,8,5,2,4,6,11,15,1000,1000]
这里的1000为脏数据,使用3σ准则进行数据清洗
这里我们需要使用apache.commons.math3包
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
在程序代码中引用
import org.apache.commons.math3.stat.StatUtils;
import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation;
import org.apache.commons.math3.stat.descriptive.rank.Median;
import com.alibaba.fastjson.JSON;
代码为:
/**
* @Author zhongkai
* @Date 2021/2/20 16:31
* @Description 3σ准则过滤
**/
public static List<Double> sigma3Filter(List<Double> data){
List<Double> returnList= new ArrayList<>(data);
double[] dataA = new double[data.size()];
for (int i=0;i<data.size();i++){
dataA[i]=data.get(i);
}
List<Double> outliersList = sigma(dataA,dataA,3);
for (double vo:outliersList){
if (returnList.contains(vo)){
returnList.remove(vo);
}
}
return returnList;
}
/**
* @Author zhongkai
* @Date 2021/2/20 14:31
* @Description x sigema准则计算
* @param data 原始数据数组
* @param arr 需要对比的数据数组
* @param x sigema的个数 一般使用3σ则x=3 样本数量一般要大于等于30个
**/
public static List<Double> sigma(double[] data,double[] arr, int x){
double avg = StatUtils.mean(data);
System.out.println("算数平均值μ:"+avg );//算数平均值
StandardDeviation standardDeviation =new StandardDeviation();
double stDev = standardDeviation.evaluate(data);
System.out.println("标准差σ为:" + stDev);
List<Double> outliersList=new ArrayList<>();
for (double vo:arr){
//判断异常值方法
if(Math.abs(vo-avg)>(x*stDev)) {
outliersList.add(vo);
System.out.println("使用"+x+"σ准则进行过滤,该数组中的"+vo+"属于异常值!");
}
}
return outliersList;
}
调用:
public static void main(String[] args) {
double[] data =new double[] {1,2,8,10,8,5,2,4,6,11,15,1,2,8,10,8,5,2,4,6,11,15,1000,1000};//原始数组
List<Double> dataList=new ArrayList<>();
for (double vo:data){
dataList.add(vo);
}
List<Double> outliersList = sigma3Filter(dataList);
System.out.println(JSON.toJSONString(outliersList));
}