题目:统计每一个小时的TOP3广告的ID;
val conf = new SparkConf().setAppName("sc").setMaster("local[*]")
val sc = new SparkContext(conf)
val format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
rdd.map(x=>{
val str = x.split("\\s+")
val date = new Date(str(0).toLong)
val hours = date.getHours
(hours,str(4))
}).groupByKey().foreach(x=>{
sc.makeRDD(x._2.toList).map(x => (x, 1)).reduceByKey(_+_).sortBy(_._2,false)
.take(3).foreach(y=>println("小时:"+x._1+"广告id:"+y._1))
})
其中变量sc是SparkContext的实例,它是运行在Driver端的,不能在Rdd中去调用sc,否则的话就会报序列化错误,如何解决,作者正在想
sparkcontext不能用在算子当中,
我们必须换一种 方式去完成数据分析
作者这里是利用sparkcore统计每一个小时的TOP3广告的ID;
时间戳 省份id 城市id 用户id 广告id
1595162391050 9 8 74 17
1595162391058 5 5 69 0
1595162391058 7 0 33 8
1595162391058 3 0 93 5
1595162391058 5 4 98 0
1595162391058 1 8 50 12
1595162391058 8 9 89 11
1595162391058 5 8 91 6
1595162391058 1 4 80 2
1595162391058 8 9 32 12
1595162391058 8 7 96 12
1595162391058 6 2 79 10
1595162391058 3 8 34 18
1595162391058 5 6 86 7
1595162391058 5 5 6 6
1595162391058 7 8 81 13
1595162391058 6 7 63 18
1595162391058 8 2 6 18
1595162391058 2 7 85 9
1595162391058 8 3 27 7
1595162391058 9 6 1 18
1595162391058 9 4 49 14
//首先肯定要读取数据
val conf = new SparkConf().setAppName("sc").setMaster("local[1]")
val sc = new SparkContext(conf)
val rdd = sc.textFile("src\\main\\resources\\adv.log")
//设置当前的日志等级是什么
sc.setLogLevel("ERROR")
val rdd1=rdd.map(x=>{
//每一行进行分割
val str=x.split("\\s+")
//我们首先对时间戳进行转换
var date=new Date(str(0).toLong)
val hour=date.getHour
//我们解读题意,每一小时id的前三名,那么我们可以将小时和id当作key值,去进行统计计算
((hour,str(4)),1)
}).reduceByKey(_+_)
//当初作者做到这里不知道该怎么办了,不知道有什么好思路,作者出去转了一圈,突然灵机一动
//我们可以再利用map,将小时设成key值,利用groupByKey对小时进行分组
//再利用mapValues对迭代器进行分析,就ok了
.map(x=>{
(x._1._1,(x._1._2,x._2)))
}).groupByKey().mapValues(x=>{
//迭代器不好做排序,我们将迭代器转成list格式
x.toList().sortBy(_.2).reverse().take(3)
}).collect().foreach(println(_))
//mapValues()算子map独有的,是对map中values进行分析的
效果截图:
做题思路:当我们需要用到两个条件进行分析是,我们可以利用map将这个两个条件当作key,然后利用其他算子,进行分析,可以再利用map转成我们所需要的东西
对迭代器里面的数据进行分析的时候我们要首先将迭代器转化成list集合在进行分析