1.计算每个学生这两门课程的总成绩,并且排序输出前5名
2.找出单科成绩为100的学生ID,最终的结果需要集合到一个RDD中
3.求每个学生这两门成绩的平均值
4.合并这个三个表,汇总学生成绩并以文本格式存储,数据汇总为学生ID,姓名,大数据成绩,数学成绩,总分,平均分。比如 1002,王一磊,94,94,188,94.0
1001 李正明
1002 王一磊
1003 陈志华
1004 张永丽
1005 赵信
1006 古明远
1007 刘浩明
1008 沈彬
1009 李子琪
1010 王嘉栋
1011 柳梦文
1012 钱多多
学号 课程 分数
1001 大数据基础 90
1002 大数据基础 94
1003 大数据基础 100
1004 大数据基础 99
1005 大数据基础 90
1006 大数据基础 94
1007 大数据基础 100
1008 大数据基础 93
1009 大数据基础 89
1010 大数据基础 78
1011 大数据基础 91
1012 大数据基础 84
1001 应用数学 96
1002 应用数学 94
1003 应用数学 100
1004 应用数学 100
1005 应用数学 94
1006 应用数学 80
1007 应用数学 90
1008 应用数学 94
1009 应用数学 84
1010 应用数学 86
1011 应用数学 79
1012 应用数学 91
第一题
/*
得到的RDD bigdata及math的数据,取出成绩排名前5的学生成绩信息
*/
//创建SparkConf对象
val conf = new SparkConf().setMaster("local[*]").setAppName("ranking")
//创建上下文对象
val sc = new SparkContext(conf)
//读取外部存储文件
val bigdata: RDD[String] = sc.textFile("D:\\ChromeCoreDownloads\\result_bigdata.txt")
val math: RDD[String] = sc.textFile("D:\\ChromeCoreDownloads\\result_math.txt")
//对两个表进行连接
val score = bigdata.union(math)
//将连接后的表score中的每行数据按“\t”分割成集合,并将集合中的学号和分数组合中k-v,学号转换成Int
val rdd1 = score.map(_.split("\t")).map(x => (x(0) -> x(2).toInt))
//将key学号相同的value进行聚合,
//top()底层调用的是takeOrdered(),我们也直接可以用takeOrdered(10)(Ordering.by(e => e._2) 这种写法叫函数柯里化
val value = rdd1.reduceByKey(_+_).top(5)(Ordering.by(e => e._2))
//输出结果
value.foreach(println)
运行结果
(1003,200)
(1004,199)
(1007,190)
(1002,188)
(1008,187)
第二题
//创建SparkConf对象
val conf = new SparkConf().setMaster("local[*]").setAppName("ranking")
//创建上下文对象
val sc = new SparkContext(conf)
//读取外部存储文件
val bigdata: RDD[String] = sc.textFile("D:\\ChromeCoreDownloads\\result_bigdata.txt")
val math: RDD[String] = sc.textFile("D:\\ChromeCoreDownloads\\result_math.txt")
//取两个RDD的交集(合并)
val collect = bigdata.union(math)
//取出所需要的字段
val tuple = collect.map(line => {
val fields = line.split("\t")
val id = fields(0)
val sorce = fields(2)
(id -> sorce)
})
//过滤掉成绩不是100分的学生
val res = tupled.distinct().filter(_._2 == "100")
res.foreach(println)
运行结果
(1007,100)
(1003,100)
(1004,100)
第三题
//求每个学生这两门成绩的平均值
//方法一:
//直接使用combineByKey算子对value值进行转换,计数,求和等操作,最后map求出平均值
val res = tuple.combineByKey((_, 1),
(acc: (Int, Int), v) => (acc._1 + v, acc._2 + 1),
(acc: (Int, Int), acc2: (Int, Int)) => (acc._1 + acc2._1, acc._2 + acc2._2)
).map(a => a._1 -> a._2._1 / a._2._2)
println("方法一:每个学生这两门成绩的平均值:")
res.collect().foreach(println)
println("-------------------------------------")
/*
方法二:解题步骤
1.通过groupByKey算子,对key进行分组
2.使用mapValues将分组后的k-v值的 v 转成list,以便于后面使用list的sum size方法
3.使用map对value值 求和并除以list的大小 从而求出平均值
*/
val res2 = tuple.groupByKey().mapValues(_.toList).map(a => a._1 -> a._2.sum/a._2.size)
println("方法二:每个学生这两门成绩的平均值:")
res2.foreach(println)
运行结果
因为运行过程中经历了shuffle阶段,导致结果返回顺序可能不一致
方法一:每个学生这两门成绩的平均值:
(1005,92)
(1012,87)
(1001,93)
(1009,86)
(1002,94)
(1006,87)
(1010,82)
(1003,100)
(1007,95)
(1008,93)
(1011,85)
(1004,99)
-------------------------------------
方法二:每个学生这两门成绩的平均值:
(1002,94)
(1006,87)
(1010,82)
(1003,100)
(1005,92)
(1008,93)
(1012,87)
(1011,85)
(1001,93)
(1004,99)
(1009,86)
(1007,95)
第四题
def main(args: Array[String]): Unit = {
/*
合并这个三个表,汇总学生成绩并以文本格式存储,
数据汇总为学生ID,姓名,大数据成绩,数学成绩,总分,平均分。比如 1002,王一磊,94,94,188,94.0
*/
//创建SparkConf对象
val conf = new SparkConf().setMaster("local[*]").setAppName("ranking")
//创建上下文对象
val sc = new SparkContext(conf)
//读取外部存储文件
val bigdata: RDD[String] = sc.textFile("D:\\ChromeCoreDownloads\\result_bigdata.txt")
val math: RDD[String] = sc.textFile("D:\\ChromeCoreDownloads\\result_math.txt")
val stu: RDD[String] = sc.textFile("D:\\ChromeCoreDownloads\\student.txt")
//将bigdata和math的成绩表合并
val score:RDD[String] = bigdata.union(math)
val scoreRDD:RDD[(String,Int)] = score.map(line => {
val field = line.split("\t")
field(0) -> field(2).toInt
})
//求出总成绩,平均分,并返回 (学号,(成绩,成绩,总成绩,平均分)) 的结构
val scoreRes:RDD[(String,(Int,Int,Int,Double))] = scoreRDD.groupByKey().
mapValues(_.toList).map(a => a._1 -> (a._2(0),a._2(1),a._2.sum,a._2.sum.toDouble/2))
//转换stu结构
val stuRDD:RDD[(String,String)] = stu.map(line => {
val field = line.split("\t")
field(0) -> field(1)
})
//转换成最终结构
val result = stuRDD.join(scoreRes).map(a => (a._1,a._2._1,a._2._2._1,a._2._2._2,a._2._2._3,a._2._2._4))
//存储
result.saveAsTextFile("ouput")
result.foreach(println)
}
运行结果
(1002,王一磊,94,94,188,94.0)
(1008,沈彬,93,94,187,93.5)
(1010,王嘉栋,78,86,164,82.0)
(1011,柳梦文,91,79,170,85.0)
(1003,陈志华,100,100,200,100.0)
(1005,赵信,90,94,184,92.0)
(1007,刘浩明,100,90,190,95.0)
(1012,钱多多,84,91,175,87.5)
(1004,张永丽,99,100,199,99.5)
(1006,古明远,94,80,174,87.0)
(1001,李正明,90,96,186,93.0)
(1009,李子琪,89,84,173,86.5)