用户定义的聚合函数 Spark Java - 合并问题

时间:2021-06-02 13:13:37

标签: java apache-spark apache-spark-sql aggregate-functions user-defined-functions

我正在尝试按照文档 here 使用用户定义的聚合函数,我想首先将 2 个值 x 和 y 传递给 SimpleRegression,然后通过执行追加合并 simpleRegression。我的问题是 reduce 函数正确接收值(如果我要求它打印 x 和 y,它会正确打印它们),但是如果我看到在merge 函数(使用提供的代码中所示的 getN() 方法)它返回我没有向这些回归器添加任何值,也就是说,好像没有对它们执行 addData() ,为什么会这样?我做错了什么?

显然这不允许我做我想做的事:获取每条回归线的斜率和截距,因为执行 finish 函数时回归量是空的,因此斜率和截距设置为NaN。

这是我的代码(Java):

public static class RegressorAggregator extends Aggregator<Tuple2<Long, Long>, SimpleRegressionWrapper, LineParameters> {


    //Valore zero per l'aggregazione - dovrebbe soddisfare a+zero=a;
    public SimpleRegressionWrapper zero(){
        return new SimpleRegressionWrapper();
    }

    public SimpleRegressionWrapper reduce(SimpleRegressionWrapper simpleRegression, Tuple2<Long, Long> xy){
        double x = (double)xy._1;
        double y = (double)xy._2;
        simpleRegression.addData(x,y);
        return simpleRegression;
    }

    public SimpleRegressionWrapper merge(SimpleRegressionWrapper a, SimpleRegressionWrapper b){
        Logger log = LogManager.getLogger(getClass().getSimpleName());
        log.error(a.getN() + " " + b.getN());
        a.append(b);
        return a;
    }

    public LineParameters finish(SimpleRegressionWrapper simpleRegression){
        return new LineParameters(simpleRegression.getSlope(), simpleRegression.getIntercept());
    }

    public Encoder<SimpleRegressionWrapper> bufferEncoder(){
        return Encoders.bean(SimpleRegressionWrapper.class);
    }

    public Encoder<LineParameters> outputEncoder(){
        return Encoders.bean(LineParameters.class);
    }

}

1 个答案:

答案 0 :(得分:0)

这个问题可以通过改变这个来解决:

public Encoder<SimpleRegressionWrapper> bufferEncoder(){
        return Encoders.bean(SimpleRegressionWrapper.class);
    }

进入这个:

public Encoder<SimpleRegressionWrapper> bufferEncoder(){
        return Encoders.javaSerialization(SimpleRegressionWrapper.class);
    }