一、分组取TopN算法
- 所谓“分组取TopN”其实就是在给定的一堆杂乱无章的数据中根据一个或多个分组的依据对数据先进行分组,然后在分好组的每一组数据内,再根据一个维度或者多个维度对组内的数据进行排序,然后找出每个小组的组内TopN的元素,这就是分组取TopN。
- 分组取TopN在数据处理过程中非常之常见,也非常的有意义,比如电商平台想找出本季度最受欢迎的Top5商品种类,且要找出Top5商品种类中每个种类的TopN受欢迎的商品,这就用到了分组取TopN算法,下面会基于一个需求来使用这个算法并配合Spark算子来完成比较复杂的业务逻辑。
二、需求分析及实现逻辑
三、需求分步骤实现详细代码讲解
1.从数据源读取数据创建RDD
JavaRDD<String> studentRDD = sc.textFile("C:\\Users\\XJH\\Desktop\\student.txt");
2.处理原始数据,创建元组RDD
JavaPairRDD<String,String> classid2Student = studentRDD.mapToPair(
new PairFunction<String, String, String>() {
public Tuple2<String, String> call(String student) {
String[] studentMessage = student.split("\t");
String classID = studentMessage[1];
Integer chinese = Integer.valueOf(studentMessage[2]);
Integer manth = Integer.valueOf(studentMessage[3]);
Integer english = Integer.valueOf(studentMessage[4]);
Integer totalScore = chinese + manth + english;
student += "\t" + String.valueOf(totalScore);
return new Tuple2<String, String>(classID,student);
}
});
3.将数据以班级id分组
JavaPairRDD<String,Iterable<String>> classid2AllStudent = classid2Student.groupByKey();
4.计算每个班级的平均分,并将平均分作为Key,班级ID作为Value创建RDD
JavaPairRDD<Integer,String> classid2AVGScore = classid2AllStudent.mapToPair(
new PairFunction<Tuple2<String, Iterable<String>>, Integer, String>() {
public Tuple2<Integer, String> call(Tuple2<String, Iterable<String>> tuple) {
String classID = tuple._1;
int numStudents = 0;
int totalScore = 0;
Iterator<String> iterator = tuple._2.iterator();
while (iterator.hasNext()){
totalScore += Integer.valueOf(iterator.next().split("\t")[5]);
numStudents ++