TopN算法实战 排序算法RangePartitioner解密

本文介绍两种TopN算法的实现方式,一是基础TopN算法的Scala实现,通过读取文件、生成键值对并进行排序来获取前N项数据;二是分组TopN算法的Java实现,采用分组和迭代方式找出各组内的TopN数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.基础TopN算法实战
2.分组TopN算法实战
3.排序算法RangePartitioner内幕解密

知识点:
*只要是改变每一行列的数据,一般都是用Map操作
*RangePartitioner主要是依赖的RDD的数据划分成不同的范围,关键的地方是不同的范围是有序的
*Google的面试题:如何在一个不确定数据规模的范围内进行排序?(rangePartitioner的水塘抽样算法)
*HashPartitioner最大的弊端是:数据倾斜!!!极端情况下某(几)个分区拥有RDD的所有数据。
*RangePartitioner除了是结果有序的基石外,最为重要的是尽量保证每个Partition中的数据量是均匀的。
*源码中SampleSize乘以3的目的是保证在数据量特别小的分区能够抽取到足够的数据,同时保证数据量特别大的分区能够二次采样。

(1)基本TopN(Scala实现)

import org.apache.spark.{SparkConf, SparkContext}

/**
  * @author shuai.ZH
  */
object TopNBasic {
  def main(args: Array[String]): Unit = {
    val conf=new SparkConf().setAppName("TopNBasic").setMaster("local")
    val sc=new SparkContext(conf)
    //读取数据
    val lines=sc.textFile("C:\\Users\\Administrator\\Desktop\\1.txt")
    val pairs=lines.map(line=>(line.toInt,line)) //生成Key-value键值对方便sortByKey进行排序
    val sortedpairs=pairs.sortByKey(false)  //降序排序
    val sortedData=sortedpairs.map(pair=>pair._2)  //过滤出排序的内容本身
    val top5=sortedData.take(5) //获取排名前五位的元素内容,元素内容构建成为一个Array
    top5.foreach(println)
  }

}

(2)Java实现分组排序

import java.util.Arrays;
import java.util.Iterator;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.api.java.function.VoidFunction;

import scala.Tuple2;

/**
 * 使用Java开发TopN分组程序
 * @author Shuai.Zh
 *
 */
public class TopNGroup {
    public static void main(String[] args) {

        SparkConf conf=new SparkConf();
        conf.setAppName("TOPNGroup");
        conf.setMaster("local");
        JavaSparkContext sc=new JavaSparkContext(conf);
        JavaRDD<String> lines=sc.textFile("C:\\Users\\Administrator\\Desktop\\1.txt");

        //把每行数据变成符合要求的key-value的方式
        JavaPairRDD<String, Integer> pairs=lines.mapToPair(new PairFunction<String, String, Integer>() {

            @Override
            public Tuple2<String, Integer> call(String line) throws Exception {
                // TODO Auto-generated method stub
                String[] splitedLine=line.split(" ");
                return new Tuple2<String, Integer>(splitedLine[0],Integer.valueOf(splitedLine[1]));

            }
        });

        //groupBy进行分组
        JavaPairRDD<String, Iterable<Integer>> groupPairs=pairs.groupByKey();
        JavaPairRDD<String, Iterable<Integer>> top5=groupPairs.mapToPair(new PairFunction<Tuple2<String,Iterable<Integer>>, String,Iterable<Integer>>() {

            @Override
            public Tuple2<String, Iterable<Integer>> call(Tuple2<String, Iterable<Integer>> groupedData) throws Exception {
                // TODO Auto-generated method stub
                Integer[] top5=new Integer[5]; //保存top5的数据本身
                String groupedKey=groupedData._1;  //获得分组组名
                Iterator<Integer> groupedValue=groupedData._2.iterator();   //获取每组的内容
                while(groupedValue.hasNext()){//查看是否有下一个元素,如果有则继续进行循环
                    Integer value=groupedValue.next();   //获取当前循环的远元素本省的内容

                    for(int i=0;i<5;i++){  //具体实现分分组内部的topN
                        if(top5[i]==null){
                            top5[i]=value;
                            break;
                        }else if(value>top5[i]){
                            for(int j=4;j>i;j--){
                                top5[j]=top5[j-1];
                            }
                            top5[i]=value;
                            break;
                        }
                    }

                }
                return new Tuple2<String, Iterable<Integer>>(groupedKey, Arrays.asList(top5));
            }
        });

        //打印分组后的TopN
        top5.foreach(new VoidFunction<Tuple2<String,Iterable<Integer>>>() {

            @Override
            public void call(Tuple2<String, Iterable<Integer>> topped) throws Exception {
                // TODO Auto-generated method stub
                System.out.println("Group Key :"+topped._1);  //获取Group Key
                Iterator<Integer> toppedValue =topped._2.iterator();   //获取 group  value

                while(toppedValue.hasNext()){  //具体打印出每组的topn 
                    Integer value=toppedValue.next();
                    System.out.println(value);
                }
                System.out.println("********************");
            }
        });
        sc.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值