SparkRDD编程练习

本文介绍了Spark中RDD的常用算子,如map、mapPartitions、foreach、foreachPatition等,并通过具体练习题目展示了如何使用这些算子来处理大规模数据,包括计算IP数量、找出特定条件的IP、统计用户出现次数及IP个数,以及找到IP最多的前K个用户。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spark中的常用算子(map,mapPartitions,foreach,foreachPatition)

前言

map:用于遍历RDD,将函数应用于每一个元素,返回新的RDD(transformation算子)

foreach:用于遍历RDD,将函数应用于每一个元素,无返回值(action算子)

mapPatitions:用于遍历操作RDD中的每一个分区,返回生成一个新的RDD(transformation算子)

foreachPatition:用于遍历操作RDD中的每一个分区,无返回值(action算子)

总结:一般使用mapPatitions和foreachPatition算子比map和foreach更加高效,推荐使用。

RDD的操作

今天学习了一下Spark中的RDD的编程,熟悉了一下RDD常用的接口,看到网上有一道题,使用RDD的接口去实现了一下,RDD编程确实强大!

练习题目

如下:在(ip user)的键值对中(空格分隔),如 

a.text 
127.0.0.1 xiaozhang 
127.0.0.1 xiaoli 
127.0.0.2 wangwu 
127.0.0.3 lisi 
….. 
B.text 
127.0.0.4 lixiaolu 
127.0.0.5 lisi 
127.0.0.3 zhangsan 

每个文件至少有1000万行,请用程序完成以下工作:
1.各个文件的ip数(涉及算子和RDD操作:map、collect)

val sc = new SparkContext(conf)
val rdd = sc.textFile("a.text").map {
      line =>
        val urls = line.split(" ")
        urls(0)
}.collect()

2.出现在b.text而没有出现在a.text的IP(涉及算子和RDD操作:map、contains)
与第1个类似,通过spark的map算子将每一行分隔,先得到文件b.text中所有的IP,然后,
该题目解题思路和第一题类似,首先可以参考第1题的方法分别获取两个文件中的IP,然后我们可以利用RDD提供的filter和contains接口,过滤出满足出现在b.text而没有出现在a.text中的IP

val sc = new SparkContext(conf)
//a.text中的ip
val rdd1 = sc.textFile("a.text").map {
      line =>
        val urls = line.split(" ")
        urls(0)
}.collect()

//b.text中的ip
val rdd2 = sc.textFile("b.text").map {
      line =>
        val urls = line.split(" ")
        urls(0)
}.collect()

//出现在b.text而没有出现在a.text的IP
rdd2.filter {
    line => 
          !rdd1.contains(line)
}.foreach(println)

3.每个user出现的次数以及每个user对应的IP的个数 (涉及算子和RDD操作:map、union、reduceByKey)
1)每个user出现的次数

//a.text中每个user出现的次数
val rdd1 = sc.textFile("a.text").map {
            line =>
              val urls = line.split(" ")
              urls(1)
      }.map(word=>(word,1)).reduceByKey(_+_)

//b.text中每个user出现的次数
val rdd1 = sc.textFile("b.text").map {
            line =>
              val urls = line.split(" ")
              urls(1)
      }.map(word=>(word,1)).reduceByKey(_+_)     
//两个文件中每个user出现的次数
val rdd3 =    rdd1.union(rdd2).reduceByKey(_+_)

2)每个user对应的IP个数

val rdd1 = sc.textFile("a.text").map{
            line =>
                val user = line.split(" ")
                user(1)
        }.collect()

        val rdd2 = sc.textFile("b.text").map{
            line =>
                val user = line.split(" ")
                (user(1), user(0))
        }

        val rdd3 = sc.textFile("a.text").map{
            line =>
                val user = line.split(" ")
                (user(1), user(0))
        }

         rdd3.union(rdd2).groupByKey().sortByKey().map{
            row =>
                val userNames = row._2.toArray
                (row._1,(userNames.mkString(",")))
        }.foreach{
            row =>
            println(row._1 + " " + row._2)
        }

4.对应IP数最多的前K个user
  该题与第3题是反向的,只需要先获取每个ip对应的用户,代码示例如下:

val rdd1 = sc.textFile("a.text").map{
            line =>
                val user = line.split(" ")
                user(0)
        }.collect()

        val rdd2 = sc.textFile("b.text").map{
            line =>
                val user = line.split(" ")
                (user(0), user(1))
        }

        val rdd3 = sc.textFile("a.text").map{
            line =>
                val user = line.split(" ")
                (user(0), user(1))
        }
        

         rdd3.union(rdd2).groupByKey().sortByKey().map{
            row =>
                val userNames = row._2.toArray
                (row._1,(userNames.mkString(",")))
        }.foreach{
            row =>
            println(row._1 + " " + row._2)
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值