spark-------------RDD 转换算子-----案例实操(求出每个省份广告点击量排名前三)

数据准备:

agent.log:时间戳,省份,城市,用户,广告,中间字段使用空格分隔。

数据截图:

需求描述:

统计出每一个省份每个广告被点击数量排行的 Top3

需求分析:

  • 1、拆分数据,将每条数据转化为 ===> ((省份,广告),1)

  • 2、对相同的key进行累加求和

  • 3、重新拆分数据,将数据由((省份,广告),总点击量) ====> (省份,(广告,总点击量))

  • 4、按key进行分组

  • 5、对同一组按照降序的进行排序,并取前三名

  • 6、输出结果

代码:

package com.xiao.spark.core.rdd.operator.tranform

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

object Spark03_RDD_Operator_AnLi {
  def main(args: Array[String]): Unit = {
      // TODO 准备环境
      val sparkConf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("transform")
      val sc = new SparkContext(sparkConf)
      // 获取数据 时间戳,省份,城市,用户,广告,中间字段使用空格分隔。
      val rdd: RDD[String] = sc.textFile("datas/agent.log")
      // 分割数据 ((省份,广告),点击次数)
      val mapRDD: RDD[((String, String), Int)] = rdd.map {
        line => {
          val data: Array[String] = line.split(" ")
          //((省份,广告),点击次数)
          ((data(1), data(4)), 1)
        }
      }
      // 对key值数据相同进行累加
      val reduceRDD: RDD[((String, String), Int)] = mapRDD.reduceByKey(_ + _)
      // 重新分配数据
      val newMapRDD: RDD[(String, (String, Int))] = reduceRDD.map {
        case ((pro, ad), num) => {
          (pro, (ad, num))
        }
      }
      // 进行分组
      val groupRDD: RDD[(String, Iterable[(String, Int)])] = newMapRDD.groupByKey()
      // 进行排序,并获取点击量最多的前三个名
      val sortRDD: RDD[(String, List[(String, Int)])] = groupRDD.mapValues(
        // 按点击量排名,默认是升序,take(3)取前三名
        iter => iter.toList.sortBy(_._2)(Ordering.Int.reverse).take(3)
      )
      sortRDD.collect().foreach(println)
      // TODO 关闭环境
      sc.stop()
  }
}

运行结果:

posted @ 2021-01-28 13:47  littlemelon  阅读(213)  评论(0编辑  收藏  举报