RDD初级编程

我们的数据集为Data01.txt,该数据集包含了某大学计算机系的成绩,数据格式如下所示:
Tom,DataBase,80
Tom,Algorithm,50
Tom,DataStructure,60
Jim,DataBase,90
Jim,Algorithm,60
Jim,DataStructure,80

下面给上数据的链接
链接:https://pan.baidu.com/s/1807ykYwSLRuHnd9tYzEopw
提取码:2xdm

打开spark-shell

这里我们使用spark-shell连接上yarn

spark-shell --master yarn

连接上之后我们就可以进入交互界面了

scala>

然后导入我们实验用的数据,我的数据放在hdfs上面了所以用如下方式导入,具体导入可以根据自己文件放的位置决定(注意用HDFS的话路径为HDFS://ip:端口/路径,用本地文件是file:///路径,不然可能报错)

scala> val input=sc.textFile("HDFS://namenode:9000/Data01.txt")
input: org.apache.spark.rdd.RDD[String] = HDFS://namenode:9000/Data01.txt MapPartitionsRDD[3] at textFile at <console>:24

具体问题

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

  1. 分析输入文件的格式,可以看到每行是一个字符串,RDD读入时,会将每行作为一个元素,我们要统计该系共有多少人,应该先从上表获得共有多少人的成绩,然后将其去重,最后count一下就可以得到总人数

    input.map(line=>line.split(",")(0)).distinct().count()
    res0: Long = 265 
    
  2. map表示对该RDD中的每个元素做下面函数中的操作

  3. line=>line.split(",")表示将每个元素用","分隔开转化为一个数组,然后将该数组的第一个值赋给新RDD的每个元素

  4. distinct():对RDD中的元素进行去重

  5. count():返回RDD中的元素个数

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

  1. 该题和第一题思想是一样的,一个统计的是有多少不同的人,一个统计的是有多少不同的课程

  2. 代码

    scala> input.map(line=>line.split(",")(1)).distinct().count()
    res4: Long = 8
    

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

  1. 求平均分首先我们想到的做法是,找到所有叫Tom的人,将他所有的分数加起来,然后用总分除以总课程数就可以得到平均分

  2. 所以我们先找到叫Tom的人

    scala> val Tom=input.filter(t => t.split(",")(0) == "Tom")
    Tom: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[14] at filter at <console>:25
    
  3. 然后我们构造一种数据结构(Tom,(成绩,1)),这样的话我们就可以得到Tom的总课程成绩以及总课程门数

    scala> val Tom_1=Tom.map(t => (t.split(",")(0), (t.split(",")(2).toInt,1)))
    Tom_1: org.apache.spark.rdd.RDD[(String, (Int, Int))] = MapPartitionsRDD[4] at map at <console>:25
    
  4. 然后我们将上面得到的(成绩,1)全部加起来

    scala> val Tom_2=Tom_1.reduceByKey((a,b)=>(a._1+b._1,a._2+b._2))
    Tom_2: org.apache.spark.rdd.RDD[(String, (Int, Int))] = ShuffledRDD[5] at reduceByKey at <console>:25
    
  5. 最后我们只要将总成绩除以总课程数即可

    scala> Tom_2.mapValues(a=>a._1/a._2).first()
    res6: (String, Int) = (Tom,30)
    

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

  1. 类似上面第三题的思想,不用过滤人名了,这次将(课程,1)作为新构建的数据结构,同时本次只关心课程门数,所以课程那个位置放什么都可以,有了上面一题得到基础,这次我们可以直接写出完整的代码
  2. 代码
    scala> input.map(t=>(t.split(",")(0), (t.split(",")(1),1))).reduceByKey((a,b)=>(a._1,a._2+b._2)).mapValues(a=>a._2).foreach(println)
    (Bartholomew,5)
    (Lennon,4)
    (Joshua,4)
    (Tom,5)
    ...
    

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

  1. 本题思路很简单,过滤出课程名是"DataBase"的课程即可

  2. 代码

    scala> input.filter(t => t.split(",")(1)=="DataBase").count()
    res16: Long = 126
    

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

  1. 本题思路和求Tom的平均分一致,这里不过将Tom改成了课程名而已,同样的这里求所有课程的平均分,所以不需要过滤

  2. 代码

    scala> input.map(t=>(t.split(",")(1), (t.split(",")(2).toInt,1))).reduceByKey((a,b)=>(a._1+b._1,a._2+b._2)).mapValues(a=>a._1/a._2).foreach(println)
    (Python,57)
    (OperatingSystem,54)
    (CLanguage,50)
    (Software,50)
    (Algorithm,48)
    (DataStructure,47)
    (DataBase,50)
    (ComputerNetwork,51)
    

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

  1. 首先,我们过滤出DataBase这门课,然后构造数据结构(“Database”,1),这样我们只要将所有元素的value相加即可

    scala> val database=input.filter(t=>t.split(",")(1)=="DataBase").map(t=>(t.split(",")(1),1))
    database: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[3] at map at <console>:25
    
  2. 然后我们构造一个累加器来进行对1的累加

    scala> val counter=sc.longAccumulator("database_counter")
    counter: org.apache.spark.util.LongAccumulator = LongAccumulator(id: 1, name: Some(database_counter), value: 0)
    
  3. 进行累加得到结果

    scala> database.values.foreach(a=>counter.add(a))
    scala> counter.value
    res5: Long = 126
    

总结

RDD编程,灵巧方便,但由于可以使用的方法较多,要多熟悉给中方法的含义,面对问题先分析再进行编程,这样由于水平有限,只能做到这一步,后面还有更多的问题要去解决,还是需要持续的学习

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值