SparkRDD学习之map ,flatmap,mappartitions,glom,union,cartesian,groupby,filter,distinct,subtract代码

import org.apache.spark.sql.SparkSession

import scala.collection.mutable.ArrayBuffer

/**
  * Created by LE on 2017/3/23.
  */
object DemoTransformations {
  //spark入口
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder.appName("DemoTransformations").master("local[*]").getOrCreate()
    val sc = spark.sparkContext


    //RDD算子
    //map
    {
      val list = 1 to 30
      val rdd = sc.parallelize(list).map(a => a * a) //1-30的每个数自乘
      println(rdd.collect.mkString(";")) //collect相当于一个汇总

      val list1 = new ArrayBuffer[Int]()

      def fun_map(a: Int): Int = {
        return a * 2
      }

      for (i <- list1) {
        list1.append(fun_map(i)) //把fun_map()追加到list1里面
      }
      println(list1.mkString(","))
      println("$" * 50)
    }
    //flatMap
    {
      val list2 = Array("abc def", "x,y,z")
      val rdd2 = sc.parallelize(list2).flatMap(_.split("|,"))
      println(rdd2.collect.mkString(";")) //;a;b;c; ;d;e;f;;x;,;y;,;z

      val rdd3 = sc.parallelize(list2).map(_.split("|,")).collect //,a,b,c, ,d,e,f
      rdd3.foreach(a => println(a.mkString(","))) //,x,,,y,,,z
      println("*" * 50)
    }
    //mapPartitions用户通过函数 f (iter)=>iter.f ilter(_>=3) 对分区中所有数据进行过滤,大于和等于 3 的数据保留。
    // 一个方块代表一个 RDD 分区,含有 1、 2、 3 的分区过滤只剩下元素 3。
    {
      var rdd4 = sc.parallelize(1 to 20).mapPartitions(a => a.filter(_ >= 10)) //小于等于10的数删除展示大于10的数
      rdd4.glom.foreach(a => println(a.mkString(","))) //a.mkstring表示转换类型以,分割
      println("*" * 50)
    }

    //glom函数将每个分区形成一个数组分区Array[(V1),(V2),(V3)]。
    {
      val rdd1 = sc.parallelize(1 to 20)
      rdd1.glom.foreach(a => println(a.mkString(",")))
      println(rdd1.glom.count())
      println("*" * 50)
    }


    //union返回的 RDD 数据类型和被合并的 RDD 元素数据类型
    // 相同含有V1、V2、U1、U2、U3、U4的RDD和
    // 含有V1、V8、U5、U6、U7、U8的RDD合并所有元素形成一个RDD。V1、V1、V2、V8形成一个分区,
    // U1、U2、U3、U4、U5、U6、U7、U8形成一个分区。
    {
      val list1 = Array("v1,v2")
      val list2 = Array("u1,u2,u3,u4")
      val list3 = Array("v1,v8")
      val list4 = Array("u5,u6,u7,u8")
      val rdd1 = list1.union(list2)
      val rdd2 = list3 ++ list1
      println(rdd1.mkString(","))
      println(rdd2.mkString(","))

    }

    //cartesian V1 和 另 一 个 RDD 中 的 W1、 W2、 Q5 进 行 笛 卡 尔 积 运 算
    // 形 成 (V1,W1)、(V1,W2)、 (V1,Q5)。
    {
      val rdd = sc.parallelize(1 to 5)
      val rdd1 = sc.parallelize(11 to 15)
      val rdd2 = rdd.cartesian(rdd1)

      println(rdd2.collect.mkString(";"))

      println("*" * 50)


    }

    //groupby将元素通过函数生成相应的 Key,数据就转化为 Key-Value 格式,之后将 Key 相同的元素分为一组
    {
      val rdd1 = sc.parallelize(Array("A1", "A2", "A3", "B1", "B2"))
      val rdd2 = rdd1.groupBy(_ (1)) //下划线表示每一个独立的元素 A1,A2  (1)表示元素的下标
      rdd2.foreach(println) //foreach一个循环 1,A1,B1  2,A2,B2 3, A3
      println("*" * 50)
    }
    //filter对元素进行过滤
    {
      val rdd = sc.parallelize(1 to 10)
      //1-10 个元素
      val rdd1 = rdd.filter(_ > 5) //小于5的元素过滤掉
      println(rdd1.collect.mkString(";"))
      println("*" * 50)
    }


    //distinct将RDD中的元素进行去重操作
    {
      val rdd = sc.parallelize((1 to 10) ++ (6 to 15))
      //++相当于连接符
      val rdd1 = rdd.distinct()
      println(rdd.collect.mkString(";")) //把1-10和6-15汇总到一起
      println(rdd1.collect.mkString(";")) //把1-10和6-15之间相同的去掉后的汇总
      println("*" * 50)
    }

    //subtract进行集合的差操作
    {
      val rdd1 = sc.parallelize(1 to 10)
      val rdd2 = sc.parallelize(6 to 15)
      val rdd3 = rdd1.subtract(rdd2)//把1-10和6-15之间的数进行相减12345
      val rdd4 = rdd2.subtract(rdd1)//11,12,13,14,15
      println(rdd3.collect.mkString(";"))
      println(rdd4.collect.mkString(";"))
      println("*" * 50)
    }
 //sample 将 RDD 这个集合内的元素进行采样,获取所有元素的子集
    {
      val rdd = sc.parallelize(1 to 100)
      val rdd1 = rdd.sample(false, 0.5)
      println(rdd1.collect.mkString(";"))
      val rdd2 = rdd.sample(true, 0.5)
      println(rdd2.collect.mkString(";"))
//每次结果不同
      println("$"*50)
    }
    //takeSample  takeSample()函数和上面的sample函数是一个原理,但是不使用相对比例采样,
    // 而是按设定的采样个数进行采样,同时返回结果不再是RDD,而是相当于对采样后的数据进行
    
      val rdd = sc.parallelize(1 to 100)
      val rdd1 =rdd.takeSample(false,20)//去1-100之内的20为数字
      println(rdd1.mkString(","))
      println("$"*50)
    

    //mapvalues  针对(Key, Value)型数据中的 Value 进行 Map 操作,而不对 Key 进行处理。
    //
    
      val rdd1 = sc.parallelize(List("A" -> 1,"A" -> 2,"B1" -> 3,"B2" -> 4))
      val rdd2 = rdd1.mapValues(_*2)
      println(rdd2.collect.mkString(","))
      println("&"*50)//(A,2),(A,4),(B1,6),(B2,8)
    
  //combineByKey 相当于将元素为 (Int, Int) 的 RDD 转变为了
    // (Int, Seq[Int]) 类型元素的 RDD
    
      val rdd1 = sc.parallelize(Array(("A1" -> 1), ("B1" -> 2), ("B1" -> 3)))
      val rdd2 = rdd1.combineByKey(
        (a: Int) => "@" + a.toString,
        (a: String, b: Int) => a + "#" + b.toString,
        (a: String, b: String) => a + "&" + b)
      println(rdd2.collect.mkString(";"))
      println("*" * 50)
    
    //reduceByKey 通过用户自定义函数 (A,B) => (A + B) 函数,
    // 将相同 key 的数据 (V1,2) 和 (V1,1) 的 value 相加运算,结果为( V1,3)。
    
       val rdd = sc.parallelize(Array(("A1"-> 2),("B1"->4),("B1"->5)))
      val rdd1 = rdd.reduceByKey(_+_)
      println(rdd1.collect.mkString(","))
      println("$"*50)
    }
  //partitionBy如果原有RDD的分区器和现有分区器(partitioner)一致,
    // 则不重分区,如果不一致,则相当于根据分区器生成一个新的ShuffledRDD
    {
      val rdd1 = sc.parallelize(Array(("A1" -> 1), ("B1" -> 2), ("B1" -> 3)))
      val rdd2 = rdd1.partitionBy(new org.apache.spark.HashPartitioner(4))
      rdd1.glom.foreach(a => println(a.mkString(",")))
      rdd2.glom.foreach(a => println(a.mkString(",")))
      println("&" * 50)
    }
    //Cogroup函数将两个RDD进行协同划分RDD1中的数据(U1,1)、 (U1,2)
    // 和RDD2中的数据(U1,2)合并为(U1,((1,2),(2)))。
    {
      val rdd = sc.parallelize(Array(("A1" -> 1),("B1" -> 12),("B1" ->13),("E1" -> 4)))
      val rdd1 = sc.parallelize(Array(("A1" -> 11),("B1" -> 22),("C1" ->10)))
      val rdd2 = rdd.cogroup(rdd1)
      println(rdd2.collect.mkString(","))
      println("&"*50)
    }


    //join java中的for循环
    {
      val rddA = sc.parallelize(Array(("A1" -> 1), ("B1" -> 2), ("B1" -> 3)))
      val rddB = sc.parallelize(Array(("A1" -> 11), ("B1" -> 12), ("C1" -> 13)))
      // A1->((1),(11)) B1->((2,3),12)

      //A1->(1,11) B1->(2,12) B1->(3,12)
      val rdd1 = rddA.join(rddB)
      println(rdd1.collect.mkString(";"))
      println("*" * 50)
    }
  //leftOuterJoin左连接
    {
      val rddA = sc.parallelize(Array(("A1" -> 1), ("B1" -> 2), ("B1" -> 3)))
      val rddB = sc.parallelize(Array(("A1" -> 11), ("B1" -> 12), ("C1" -> 13)))

      val rdd1 = rddA.leftOuterJoin(rddB)
      println(rdd1.collect.mkString(";"))
      println("*" * 50)
    }
  // rightOuterJoin 右连接
    {
      val rddA = sc.parallelize(Array(("A1" -> 1), ("B1" -> 2), ("B1" -> 3)))
      val rddB = sc.parallelize(Array(("A1" -> 11), ("B1" -> 12), ("C1" -> 13), ("C1" -> 14)))
      // A1->((1),(11))   B1->((2,3),(12))  C1->((NULL),(13,14))

      //A1->(1,11) B1->(2,12) B1->(3,12) C1->(NULL,13) C1->(NULL,14)
      val rdd1 = rddA.rightOuterJoin(rddB)
      println(rdd1.collect.mkString(";"))
      println("*" * 50)
    }
	spark.stop()
}}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值