数据准备:
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()
}
}
运行结果: