我有一个整数的rdd(即RDD[Int]),我想做的是计算以下十个百分位数:[0th, 10th, 20th, ..., 90th, 100th]。最有效的方法是什么?

最佳答案

您可以 :

  • 通过rdd.sortBy()排序数据集
  • 通过rdd.count()计算数据集的大小
  • 带有索引的邮政编码,以方便百分位数检索
  • 通过rdd.lookup()检索所需的百分位数,例如对于第10个百分位rdd.lookup(0.1 *大小)

  • 要计算中位数和第99个百分位数:
    getPercentiles(rdd,new double [] {0.5,0.99},size,numPartitions);

    在Java 8中:

    public static double[] getPercentiles(JavaRDD<Double> rdd, double[] percentiles, long rddSize, int numPartitions) {
        double[] values = new double[percentiles.length];
    
        JavaRDD<Double> sorted = rdd.sortBy((Double d) -> d, true, numPartitions);
        JavaPairRDD<Long, Double> indexed = sorted.zipWithIndex().mapToPair((Tuple2<Double, Long> t) -> t.swap());
    
        for (int i = 0; i < percentiles.length; i++) {
            double percentile = percentiles[i];
            long id = (long) (rddSize * percentile);
            values[i] = indexed.lookup(id).get(0);
        }
    
        return values;
    }
    

    请注意,这需要对数据集O(n.log(n))进行排序,并且在大型数据集上可能会很昂贵。

    另一个建议仅计算直方图的答案将无法正确计算百分位数:这是一个反例:一个由100个数字组成的数据集,其中99个数字为0,一个数字为1。最后一个数字全部为99 0垃圾箱,最后一个垃圾箱中的1个垃圾箱,中间有8个空垃圾箱。

    关于apache-spark - 如何在Apache Spark中计算百分位数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28805602/

    10-13 05:13