Java数学描述统计删除值

Java数学描述统计删除值,java,statistics,esper,Java,Statistics,Esper,我是Java新手,一直在使用ESPERCEP引擎。然而,这个问题与Esper无关,它更像是一个Java问题 首先,我的班级:- import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import com.es

我是Java新手,一直在使用ESPERCEP引擎。然而,这个问题与Esper无关,它更像是一个Java问题

首先,我的班级:-

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;

import com.espertech.esper.epl.agg.AggregationSupport;
import com.espertech.esper.epl.agg.AggregationValidationContext;

public class CustomPercentiles extends AggregationSupport {
    private List<Double> numbers = new ArrayList<Double>();

    public CustomPercentiles(){
        super();
    }

    public void clear() {
        numbers.clear();
    }

    public void enter(Object arg0) {
        Double value = (Double) (double) (Integer) arg0;
        if (value > 0){
            //Not interested in < 1
            numbers.add(value);         
        }
    }

    public void leave(Object arg0) {
        Double value = (Double) (double) (Integer) arg0;
        if (value > 0){
            //Not interested in < 1
            numbers.remove(value);          
        }
    }

    public Object getValue() {
        DescriptiveStatistics stats = new DescriptiveStatistics();
        Map<String, Integer> result = new HashMap<String, Integer>();
        for (Double number:numbers.subList(0, numbers.size())){
            stats.addValue(number);     
        }
        result.put("median", (int) stats.getPercentile(50));
        result.put("pct90", (int) stats.getPercentile(90));
        result.put("pct10", (int) stats.getPercentile(10));
        result.put("mean", (int) stats.getMean());
        result.put("std", (int) stats.getStandardDeviation());

        return result ;
    }

    public Class getValueType() {
        return Object.class;
    }

    @Override
    public void validate(AggregationValidationContext arg0) {
        // TODO Auto-generated method stub
    }

}
在这段时间内,getValue()可能被多次调用。每次调用它时,它都会返回基于当前数字内容的计算结果

getValue()计算第10、50和90个百分位。为了计算百分位数,描述性统计需要对数字进行排序。(100个数字中的第10个百分位是排序后列表中的第10个数字。)

所以我在寻找一种方法,能够从DescriptiveStatistics实例中去掉任意数字。或者要求推荐一些其他库,这些库可以给我中间值和百分位数,同时能够在知道数值的情况下从列表中取出一个数字


DescriptiveStatistics有一个removeMostRecentValue(),但这不是我想要做的。

据我所知,您要求的是一种使用-class而不是“数字”作为列表的方法。也就是说,您希望动态地在DescriptiveStatistics变量中添加和删除数字

就我所知,没有比你现在所做的更好的方法了

在再次计算百分比之前,是否确实需要该功能从列表中删除特定数字?不总是新的数字吗

这听起来有点像你想学习更多的Java基础知识

无论如何,由于我不能真正为您的问题提供一个合格的答案,我想我至少可以帮助您更正一些代码,以遵循更好的实践:

public class CustomPercentiles extends AggregationSupport {
    private List<Double> numbers = new ArrayList<Double>();

    //Methods that are inherited from super-classes and interfaces
    //should have the "@Override" annotation,
    //both for the compiler to check if it really is inherited,
    //but also to make it more clear which methods are new in this class.
    @Override    
    public void clear() {
        numbers.clear();
    }

    @Override
    public void enter(Object value) {
        double v = (double) value;
        if (v > 0){
            numbers.add(v);            
        }
    }

    @Override
    public void leave(Object value) {
        double v = (double) value;
        if (v > 0){
            numbers.remove(v);            
        }
    }

    @Override
    public Object getValues() {
        DescriptiveStatistics stats = new DescriptiveStatistics();
        Map<String, Integer> result = new HashMap<String, Integer>();
        //It is unnecessary to call number.subList(0, numbers.size())
        //since it will just return the entire list.
        for (Double number : numbers){
            stats.addValue(number);        
        }
        result.put("median", (int) stats.getPercentile(50));
        result.put("pct90", (int) stats.getPercentile(90));
        result.put("pct10", (int) stats.getPercentile(10));
        result.put("mean", (int) stats.getMean());
        result.put("std", (int) stats.getStandardDeviation());

        return result ;
    }

    //Judgning from the API of AggregationSupport,
    //I would say this method should return Double.class
    //(it basically seems like a bad way of implementing generics).
    //Are you sure it should return Object.class?
    public Class getValueType() {
        return Object.class;
    }

    @Override
    public void validate(AggregationValidationContext arg0) {
        // TODO Auto-generated method stub
    }

}
公共类CustomPercentiles扩展了聚合支持{
私有列表编号=新的ArrayList();
//从超类和接口继承的方法
//应该有“@Override”注释,
//为了让编译器检查它是否真的被继承,
//但也要更清楚地说明哪些方法在这个类中是新的。
@凌驾
公共空间清除(){
数字。清除();
}
@凌驾
公共无效输入(对象值){
双v=(双)值;
如果(v>0){
增加(五);
}
}
@凌驾
公共作废许可(对象值){
双v=(双)值;
如果(v>0){
删除(v);
}
}
@凌驾
公共对象getValues(){
DescriptiveStatistics stats=新的DescriptiveStatistics();
映射结果=新的HashMap();
//不需要调用number.subList(0,numbers.size())
//因为它只会返回整个列表。
用于(双倍数字:数字){
stats.addValue(数字);
}
结果.put(“中位数”,(int)stats.getPercentile(50));
结果.put(“pct90”,(int)stats.getPercentile(90));
结果.put(“pct10”,(int)stats.getPercentile(10));
result.put(“mean”,(int)stats.getMean());
result.put(“std”,(int)stats.getStandardDiversion();
返回结果;
}
//从聚合支持的API判断,
//我认为这个方法应该返回Double.class
//(这基本上看起来是一种实现泛型的糟糕方式)。
//您确定它应该返回Object.class吗?
公共类getValueType(){
返回Object.class;
}
@凌驾
公共无效验证(AggregationValidationContext arg0){
//TODO自动生成的方法存根
}
}

据我所知,没有理由多次投射对象。据我所知,
Double value=(Double)(Double)(Integer)arg0应该是
Double value=(Double)arg0。此外,代码中的注释通常应该回答为什么要做某事,而不是什么。至于你的实际问题,我恐怕不能完全理解你的真正要求,对不起。你能试着详细说明你的问题吗?为什么你的
enter()
-和
leave()
-方法将
对象
作为一个参数,而唯一允许的值实际上是一个
double
?为什么你要做
numbers.subList(0,numbers.size())
?除了调用一个不必要的方法外,它产生的结果与输入数字的结果相同。。。但你的问题到底是什么?我什么地方都没看到。好吧,我读到了关于-类的文章,这对我没什么帮助。你是说你对分类有意见?是的,您可以向类中添加任意数量的字段变量。您可以指定您想要实现的目标吗?ESPERAPI中的AggregationSupport类指定enter、leave和getValues的签名;OP只是在遵循该规范regard@fd. 对,我编辑了我的答案。对我来说,Esper似乎是一大堆坏习惯。但是,我不熟悉百分位数,这似乎有点复杂,所以不幸的是,我真的不能给一个替代的好建议。
public class CustomPercentiles extends AggregationSupport {
    private List<Double> numbers = new ArrayList<Double>();

    //Methods that are inherited from super-classes and interfaces
    //should have the "@Override" annotation,
    //both for the compiler to check if it really is inherited,
    //but also to make it more clear which methods are new in this class.
    @Override    
    public void clear() {
        numbers.clear();
    }

    @Override
    public void enter(Object value) {
        double v = (double) value;
        if (v > 0){
            numbers.add(v);            
        }
    }

    @Override
    public void leave(Object value) {
        double v = (double) value;
        if (v > 0){
            numbers.remove(v);            
        }
    }

    @Override
    public Object getValues() {
        DescriptiveStatistics stats = new DescriptiveStatistics();
        Map<String, Integer> result = new HashMap<String, Integer>();
        //It is unnecessary to call number.subList(0, numbers.size())
        //since it will just return the entire list.
        for (Double number : numbers){
            stats.addValue(number);        
        }
        result.put("median", (int) stats.getPercentile(50));
        result.put("pct90", (int) stats.getPercentile(90));
        result.put("pct10", (int) stats.getPercentile(10));
        result.put("mean", (int) stats.getMean());
        result.put("std", (int) stats.getStandardDeviation());

        return result ;
    }

    //Judgning from the API of AggregationSupport,
    //I would say this method should return Double.class
    //(it basically seems like a bad way of implementing generics).
    //Are you sure it should return Object.class?
    public Class getValueType() {
        return Object.class;
    }

    @Override
    public void validate(AggregationValidationContext arg0) {
        // TODO Auto-generated method stub
    }

}