TopN算法

基本TopN

object TopNBasic{
  def main(args:Array[String]){
    val conf = new SparkConf().setAppName("TopNBase").setMaster("local")
    val sc = new  SparkContext(conf)
    val lines = sc.textFile("e:/test/basicTopN.txt")
    val pairs = lines.map(x => (x.toInt,x))  //生成Key,Value键值对
    val sortedPairs = pairs.sortByKey(false)
    val sortedData = sortedPairs.map(x => x._2) //过滤出排序后的内容本身
    val top5=sortedData.take(5) //获取排名前5的元素内容
    top5.foreach(println)   //take的返回时一个数组(不能进行collect,collect需要是RDD)
  }
}

分组TopN
java:

package com.quell.spark;

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.FlatMapFunction;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.api.java.function.VoidFunction;
import scala.Tuple2;

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

public class TOPNsort {

    public static void main(String[] args)
    {
        SparkConf conf = new SparkConf().setAppName("TopNGrouped").setMaster("local");
        JavaSparkContext sc = new JavaSparkContext(conf);
        JavaRDD<String> data = sc.textFile("E:\\test\\hello.txt");

        JavaPairRDD<String,Integer> pairs = data.mapToPair(new PairFunction<String,String,Integer>() {
            private static final long serialVersionUID =1L;
            @Override
            public Tuple2<String, Integer> call(String line) throws Exception {
                String[] splitedline = line.split(" ");
                return new Tuple2<String, Integer>(splitedline[0],Integer.valueOf(splitedline[1]));
            }
        });

        JavaPairRDD<String,Iterable<Integer>> groupedPairs = pairs.groupByKey();

        groupedPairs.foreach(new VoidFunction<Tuple2<String, Iterable<Integer>>>() {
            @Override
            public void call(Tuple2<String, Iterable<Integer>> pairs) throws Exception {
                System.out.println("Group Key :" + pairs._1);
                Iterator<Integer> toppedValue = pairs._2.iterator();
                while (toppedValue.hasNext()) {
                    Integer value = toppedValue.next();
                    System.out.println(value);
                }
            }
        });

        JavaPairRDD<String,Iterable<Integer>> top5 = groupedPairs.mapToPair(new PairFunction<Tuple2<String, Iterable<Integer>>, String, Iterable<Integer>>() {
            private static final long serialVersionUID =1L;
            @Override
            public Tuple2<String, Iterable<Integer>> call(Tuple2<String, Iterable<Integer>> groupedData) throws Exception {
                Integer[] top5 = new Integer[5];
                String groupedKey = groupedData._1;
                Iterator<Integer> groupValue = groupedData._2.iterator();
                while (groupValue.hasNext()) {
                    Integer value = groupValue.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));
            }
        });
//打印分组内容
       top5.foreach(new VoidFunction<Tuple2<String, Iterable<Integer>>>() {
            private static final long serialVersionUID =1L;
            @Override
        public void call(Tuple2<String, Iterable<Integer>> topped) throws Exception {
            System.out.println("Group Key :"+topped._1);
            Iterator<Integer> toppedValue=topped._2.iterator();
            while(toppedValue.hasNext()){
                Integer value=toppedValue.next();
                System.out.println(value);
            }
            System.out.println("*****************");
        }
    });

        sc.close();

    }
}

scala:

object TopNx {
  def main(args:Array[String]): Unit ={
  val conf = new SparkConf().setAppName("TopNx").setMaster("local")
  val sc = new  SparkContext(conf)
  val lines = sc.textFile("e:/test/TopNGroup.txt")

  val pairs = lines.map(line => (line.split(" ")(0),line.split(" ")(1).toInt)) //生成Key,Value键值对
  val groupedPairs = pairs.groupByKey()
/******************************************/
  val result = groupedPairs.map(line => {
    val groupedKey = line._1  //获取分组的组名
    val groupValue = line._2 //获取每组的内容集合
    val listBuffer = new ListBuffer[Int]
    for(i <-groupValue){
      listBuffer += i
    }
    val top5 = listBuffer.sorted(Ordering.Int.reverse).take(5)
    (groupedKey,top5)
  }).sortByKey(true)
    result.collect().foreach(pair=>{
      println(pair._1+":")
      pair._2.foreach(println)
      println("****************")
/****************************************/
    val topx = groupedPairs.map(pair=>(pair._1,pair._2.toList.sortWith(_>_).take(5))).sortByKey() //对数据,键值分别排序
  /*  top5.collect().foreach(pair=>{
      println(pair._1+":")
      pair._2.foreach(println)
      println("****************")*/
    })
/********************************************/
    sc.stop()
}
}

分组TOPN排序
1.读入每行数据
2、生成pairs K,V键值对
 输入一行的数据 输出的KEY值是名称,Value是分数
3、按名称进行分组
4、分组以后进行排序
输入groupdata,其中 KEY是名称的组名,VALUE是分数的集合
输出 KEY:分组排序以后的组名,VALUE:是排序以后的分数的集合 取5个值

排序算法RangePartitioner内幕解密
RangePartitioner主要是依赖的RDD的数据划分成不同的范围,关键的地方是不同的范围是有序的。
RangePartitioner除了是结果有序的基石以外,最为重要的是尽量保证每个Partition中的数据量是均匀的!   
采用了水塘抽样的算法

学习于:

DT大数据梦工厂
新浪微博:www.weibo.com/ilovepains/
微信公众号:DT_Spark
博客:http://.blog.sina.com.cn/ilovepains
TEL:18610086859
Email:18610086859@vip.126.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值