Spark—RDD算子使用IDEA-Scala操作练习:请根据磁盘文件“数据集”data01.txt,该数据集包含了某大学计算机系的成绩,计算下列问题。

一、数据源文件下载

https://download.csdn.net/download/weixin_45947938/66589736

二、问题描述

请根据给定的实验数据,在idea中通过Scala编程来计算以下内容:

(1)该系总共有多少学生;

(2)该系共开设来多少门课程;

(3)Tom同学的总成绩平均分是多少;

(4)求每名同学的选修的课程门数;

(5)该系DataBase课程共有多少人选修;

(6)各门课程的平均分是多少;

(7)使用累加器计算共有多少人选了DataBase这门课。

三、代码

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

object studentCount {
  def main(args: Array[String]): Unit = {

    //1、创建SparkConf对象,该对象初始化一些数据,如该scala代码程序的名字,连接到主节点master的url地址
    val sparkConf = new SparkConf().setMaster("local").setAppName("WordCount")

    //2、创建SparkContext对象,该对象时应用程序提交到spark进行计算运行的唯一入口
    val sc = new SparkContext(sparkConf)

    //通过textFile函数获取数据,同时把数据分割为一行一行,每个数据节点存储一定行数的数据,lines-RDD就是代表这些行的的名字
    val lines = sc.textFile("D://scala-spark-rdd/data/data01.txt")

    //lines-RDD调用map函数,使用split以逗号把每行的数据分割,得到一个个的单词,这些单词的数据集合就是新的student-RDD
    //reverse(2)函数代表只取该行数据里面的第二个元素,注意这里的顺序的到着来数的,如reverse(0)倒着数,就是最后一个元素
    //distinct()函数代表把这个RDD里面的数据元素进行去重,重复的删掉
    //count()函数代表计算统计该RDD里面一共有多少个元素
    val student = lines.map(s => s.split(",").reverse(2)).distinct().count()
    println("该系总共有多少学生:"+student)

    val course = lines.map(s => s.split(",").reverse(1)).distinct().count()
    println("该系共开设来多少门课程:"+course)

    //先使用过滤函数filter把包含Tom的行取出来,接着把这些行按照逗号拆分,最后使用reverse函数取某个数据,转换为int类型toInt,求和sum函数
    //接着计算tom一共出现几次
    val TomGradeAverage = lines.filter(x => x.contains("Tom")).map(x => x.split(",").reverse(0).toInt).sum() /
                           lines.filter(x => x.contains("Tom")).count()

    println("Tom同学的总成绩平均分是多少:"+TomGradeAverage)

    //求出每个同学的名字在该文件中出现的总次数就是该生选修了课的总数了,
    //将数据集RDD中的每一个元素,传入foreach函数,每个元素执行函数体println输出
    val eachStuCourseCount = lines.map(x => x.split(",").reverse(2)).map(x => (x,1)).reduceByKey(_+_).foreach(println)

    val DataBaseCount=lines.filter(x => x.contains("DataBase")).count()
    println("该系DataBase课程共有多少人选修:"+DataBaseCount)

    //x.split(",")(1)的意思是:以逗号分隔后,取第2个数据(1),下标是从0开始计算的,所以第二个数据就是下标1——意思是只取课程和成绩两个数据,姓名不要了
    //使用reduceByKey把课程一样的成绩加起来,并统计多少次,用于计算平均分
    //x._1+y._1  成绩与成绩相加  因为是加value值,key不加
    //x._2+y._2  课程名与课程名相加==>课程总数
    //mapValues——由于有两个值,所以不使用map
    val eachCourseAverage = lines.map(x => (x.split(",")(1),x.split(",")(2).toInt)).mapValues(x => (x,1)).reduceByKey((x,y) => (x._1+y._1,x._2+y._2)).
      mapValues(x => x._1.toDouble / x._2.toDouble).foreach(println)

    //使用累加器计算共有多少人选了DataBase这门课。
    val accumulatorDataBase = lines.filter(x => x.contains("DataBase"))
    val accum = sc.longAccumulator//实例化一个累加器,使用sparkcontext对象生成,累加器初始化默认从0开始
    accumulatorDataBase.foreach(x => accum.add(1))//foreach相当于遍历RDD,每传入RDD中的一个数据,就执行一次函数体代码,累加器就加1
    println("使用累加器计算共有多少人选了DataBase这门课:"+accum.value)

    //关闭入口
    sc.stop()
  }
}

四、实验结果

  • 9
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值