2021-2022年寒假学习进度19

今天完成了spark基础实验四,

一、实验目的

 

(1) 熟悉Spark 的RDD 基本操作及键值对操作;

(2) 熟悉使用RDD 编程解决实际具体问题的方法。

 

二、实验平台

 

操作系统:Ubuntu16.04 Spark 版本:2.1.0

 

三、实验内容和要求

 

1. spark-shell 交互式编程

 

请到本教程官网的“下载专区”的“数据集”中下载 chapter5-data1.txt,该数据集包含了某大学计算机系的成绩,数据格式如下所示:

 

 

 

 

 

 

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

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

 

val lines = sc.textFile("file:///opt/software/Data01.txt")

lines.map(row=>row.split(",")(0)).distinct().count

 

 

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

lines.map(row=>row.split(",")(1)).distinct().count

 

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

lines.filter(row=>row.split(",")(0)=="Tom").map(row=>(row.split(",")(0),row.split(",")(2).toInt))

.mapValues(x=>(x,1))

.reduceByKey((x,y) => (x._1+y._1,x._2 + y._2))

.mapValues(x => (x._1 / x._2))

.collect()

 

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

lines.map(row=>(row.split(",")(0),1))

.reduceByKey((x,y)=>x+y)

.collect

 

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

lines.filter(row=>row.split(",")(1)=="DataBase").count

 

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

lines.map(row=>(row.split(",")(1),row.split(",")(2).toInt))

.mapValues(x=>(x,1))

.reduceByKey((x,y) => (x._1+y._1,x._2 + y._2))

.mapValues(x => (x._1 / x._2))

.collect()

 

 

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

val accum = sc.longAccumulator("accumulateor")

lines.filter(row=>row.split(",")(1)=="DataBase")

.map(row=>(row.split(",")(1),1))

.values

.foreach(x => accum.add(x))

accum.value

 

 

2. 编写独立应用程序实现数据去重

 

对于两个输入文件A B,编写 Spark 独立应用程序,对两个文件进行合并,并剔除其中重复的内容,得到一个新文件 C。下面是输入文件和输出文件的一个样例,供参考。

输入文件A 的样例如下:

 

20170101

x

20170102

y

20170103

x

20170104

y

20170105

z

20170106

z

输入文件B 的样例如下:

 

20170101

y

20170102

y

20170103

x

20170104

z

20170105

y

根据输入的文件A 和B 合并得到的输出文件C 的样例如下:

 

20170101

x

20170101

y

20170102

y

20170103

x

20170104

y

20170104

z

20170105

y

20170105

z

20170106

z

package spark.core.exper04

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

import java.io.FileWriter

/**
 * @ClassName exper04_1.java
 * @author 赵浩博
 * @version 1.0.0
 * @Description TODO
 * @createTime 2022年01月12日 11:22:00
 */
object exper04_1 {
  def main(args: Array[String]): Unit = {

    // 配置信息
    val conf = new SparkConf().setAppName("exper04_1")
      .set("spark.executor.memory", "512m")
      .setMaster("local")
    val sc = new SparkContext(conf)

    // 读取文件A.txt
    val A = sc.textFile("E://bigdata//A.txt")
    // 读取文件B.txt"
    val B = sc.textFile("E://bigdata//B.txt")
    // 对两个文件进行合并
    val all = A++B
    // 1 用distinct()去重
    // 2 以空格切割 例如:(20170101 x)
    // 3 根据key排序
    val distinct_lines = all.distinct().map(row=>(row.split(" ")(0),row.split(" ")(1))).sortByKey()
    // 将RDD类型的数据转化为数组
    val results = distinct_lines.collect()
    // 将结果输出到C.txt中
    val out = new FileWriter("E://bigdata//C.txt",true)
    for(item<-results){
      out.write(item+"\n")
      println(item)
    }
    out.close()
  }
}

 

 

 

 

3. 编写独立应用程序实现求平均值问题

 

每个输入文件表示班级学生某个学科的成绩,每行内容由两个字段组成,第一个是学生名字,第二个是学生的成绩;编写 Spark 独立应用程序求出所有学生的平均成绩,并输出到一个新文件中。下面是输入文件和输出文件的一个样例,供参考。

Algorithm 成绩: 小明 92

小红 87

 

小新 82

90 Database 成绩: 小明 95

小红 81

小新 89

85 Python 成绩: 小明 82

小红 83

小新 94

小丽 91

平均成绩如下:

(小红,83.67)

(小新,88.33)

(小明,89.67)

(小丽,88.67)

package spark.core.exper04

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

import java.io.FileWriter

/**
 * @ClassName exper04_2.java
 * @author 赵浩博
 * @version 1.0.0
 * @Description TODO
 * @createTime 2022年01月12日 11:27:00
 */
object exper04_2 {
  def main(args: Array[String]) {

    // 配置信息
    val conf = new SparkConf().setAppName("exper04_2")
      .set("spark.executor.memory", "512m")
      .setMaster("local")
    val sc = new SparkContext(conf)


    // 读取文件Algorithm.txt
    val Algorithm = sc.textFile("E://bigdata//Algorithm.txt")
    // 读取文件Database.txt"
    val Database = sc.textFile("E://bigdata//Database.txt")
    // 读取文件Python.txt
    val Python = sc.textFile("E://bigdata//Python.txt")
    // 对三个文件进行整合
    val all = Algorithm ++ Database ++ Python
    // 以空格切割将每个名字作为键,值为一个键值对,该键值对的键为成绩,值为1(用于后面计算平均值计数用)
    // 例如:(小明, (90,1))
    val student_grade = all.map(row=>(row.split(" ")(0),(row.split(" ")(1).toInt,1)))
    // 对上述RDD做聚合,值的聚合返回一个二元组,第一个元素是该学生所有课的成绩求和,第二个元素是该学生选修课的数目,然后再做一个映射
    // 将人名作为第一个元素,所有课的总成绩除以选修课程的数目得到该学生的平均成绩作为第二个元素
    val student_ave = student_grade.reduceByKey((x,y)=>(x._1+y._1,x._2+y._2)).map(x=>(x._1,((x._2._1).toFloat/x._2._2).formatted("%.2f")))
    // 将RDD类型的数据转化为数组
    val results = student_ave.collect()
    // 将结果输出到output.txt中
    val out = new FileWriter("E://bigdata//output.txt",true)
    for(item<-results){
      out.write(item+"\n")
      println(item)
    }
    out.close()
  }
}

 

posted @ 2022-01-19 15:20  哦心有  阅读(57)  评论(0)    收藏  举报