大数据技术之Spark Core的RDD(二)

大数据技术之Spark Core的RDD(二)

一:双Value类型

  1. union(otherDattaset)案例

    作用:对源RDD和参数RDD求并集后返回一个新的RDD数据集
    需求:创建两个RDD,并求并集
    val rdd1 = sc.parallelize(1 to 5)
    val rdd2 = sc.parallelize(5 to 8)
    val rdd3 = rdd1.union(rdd2).collect()
    res18: Array[Int] = Array(1, 2, 3, 4, 5, 5, 6, 7, 8)
    
  2. subtract(otherDataset)案例

    作用:计算差的一种函数,去除两个RDD中相同的元素,不同的RDD将保留下来
    需求:创建两个RDD,求第一个RDD与第二个RDD的差集
    val rdd1 = sc.parallelize(3 to 8)
    val rdd2 = sc.parallelize(1 to 5)
    val rdd3 = rdd1.subtract(rdd2).collect()
    res27: Array[Int] = Array(8, 6, 7)
    
  3. intersection(otherDataset)案例

    作用:对源RDD和参数RDD求叫鸡后返回一个新的RDD
    需求:创建两个RDD,求交集
    val rdd1 = sc.parallelize(1 to 7)
    val rdd2 = sc.parallelize(5 to 10)
    val rdd3 = rdd1.intersection(rdd2).collect()
    res19: Array[Int] = Array(5, 6, 7)
    
  4. cartesian(otherDataset)案例:笛卡儿积,尽量避免使用

  5. zip(otherDataset)案例

    作用: 将两个 RDD 组合成 Key/Value 形式的 RDD,这里默认两个 RDD 的 partition 数量以
    及元素数量都相同,否则会抛出异常。
    需求:创建两个 RDD,并将两个 RDD 组合到一起形成一个(k,v)RDD
    val rdd1 = sc.parallelize(Array(1,2,3),3)
    val rdd2 = sc.parallelize(Array("a","b","c"),3)
    rdd1.zip(rdd2).collect
    res1: Array[(Int, String)] = Array((1,a), (2,b), (3,c))
    

二:Key-Value类型

  1. partitionBy案例

    作用:对原有pairRDD进行分区操作,如果原有的pairRDD和现有的RDD是一致的话,就不进行分区,否则会生成ShuffleRDD,即产生一个shuffle过程
    val rdd = sc.parallelize(Array((1,"aaa"),(2,"bbb"),(3,"ccc"),(4,"ddd")),4)
    //需要new 一个HashPartitioner类
    var rdd2 = rdd.partitionBy(new org.apache.spark.HashPartitioner(2))
    
    1. groupByKey案例
    作用:groupByKey也是对key进行分组操作,但只会生成一个sequence(序列)
    需求:创建一个 pairRDD,将相同 key 对应值聚合到一个 sequence 中,并计算相同 key
    对应值的相加结果。
    val words = Array("one", "two", "two", "three", "three", "three")
    val wordPairsRDD = sc.parallelize(words).map(word => (word, 1))
    val group = wordPairsRDD.groupByKey().collect()
    res1: Array[(String, Iterable[Int])] = Array((two,CompactBuffer(1, 1)), (one,CompactBuffer(1)),(three,CompactBuffer(1, 1, 1)))
    group.map(t => (t._1, t._2.sum)).collect()
    res3: Array[(String, Int)] = Array((two,2), (one,1), (three,3))
    
    
    1. reduceByKey(func,[numTasks])案例
    作用:在一个(K,V)的 RDD 上调用,返回一个(K,V)的 RDD,使用指定的 reduce 函数,将相同
    key 的值聚合到一起, reduce 任务的个数可以通过第二个可选的参数来设置。
    需求:创建一个 pairRDD,计算相同 key 对应值的相加结果
    val rdd = sc.parallelize(List((("female",1),("male",5),("female",5),("male",2))))
    val reduce = rdd.reduceByKey((x,y)=>x+y).collect()
    res29: Array[(String, Int)] = Array((female,6), (male,7))
    
    1. reduceByKey和groupByKey的区别
    1. reduceByKey:按照 key 进行聚合,在 shuffle 之前有 combine(预聚合)操作,返回结果
    是 RDD[k,v].
    2. groupByKey:按照 key 进行分组,直接进行 shuffle。
    3. 开发指导: reduceByKey 比 groupByKey,建议使用。但是需要注意是否会影响业务逻辑。
    
    1. aggregateByKey案例

    参数:(zeroValue:U,[Partitioner])(seqOp:(U,V)=>U,combOp:(U,U)=>U)

    1. 作用: 在 kv 对的 RDD 中,按 key 将 value 进行分组合并,合并时,将每个 value 和初
    始值作为 seq 函数的参数,进行计算,返回的结果作为一个新的 kv 对,然后再将结果按照
    key 进行合并,最后将每个分组的 value 传递给 combine 函数进行计算(先将前两个 value
    进行计算,将返回结果和下一个 value 传给 combine 函数,以此类推),将 key 与计算结果
    作为一个新的 kv 对输出。
    2. 参数描述:
    ( 1) zeroValue: 给每一个分区中的每一个 key 一个初始值;
    ( 2) seqOp: 函数用于在每一个分区中用初始值逐步迭代 value;
    ( 3) combOp: 函数用于合并每个分区中的结果。
    3. 需求: 创建一个 pairRDD, 取出每个分区相同 key 对应值的最大值,然后相加
    val rdd = sc.parallelize(List(("a",3),("a",2),("c",4),("b",3),("c",6),("c",8)),2)
    val agg = rdd.aggregateByKey(0)(math.max(_,_),_+_)
    agg.collect()
    res0: Array[(String, Int)] = Array((b,3), (a,3), (c,12))
    
    1. foldByKey案例
    参数:(zeroValue:V)(func:(V,V)=>V):RDD[(K,V)]
    作用:aggregateByKey的简化操作,当seqOp和combop相同时
    需求:创建一个pairRDD,计算相同key对应值的相加结果
    val rdd = sc.parallelize(List((1,3),(1,2),(1,4),(2,3),(3,6),(3,8)),3)
    val agg = rdd.foldByKey(0)(_+_)
    agg.collect()
    res61: Array[(Int, Int)] = Array((3,14), (1,9), (2,3))
    
    1. combineByKey[C]案例
    参数: (createCombiner: V => C, mergeValue: (C, V) => C, mergeCombiners: (C, C) => C)
    1. 作用:对相同 K,把 V 合并成一个集合。
    2. 参数描述:
    ( 1) createCombiner: combineByKey() 会遍历分区中的所有元素,因此每个元素的键要么还没有遇到过,
    要么就和之前的某个元素的键相同。如果这是一个新的元素,combineByKey()会使用一个叫作
    createCombiner()的函数来创建那个键对应的累加器的初始值
    ( 2) mergeValue: 如果这是一个在处理当前分区之前已经遇到的键,它会使用 mergeValue()方法将该键的累
    加器对应的当前值与这个新的值进行合并
    ( 3) mergeCombiners: 由于每个分区都是独立处理的, 因此对于同一个键可以有多个累加器。如果有两个
    或者更多的分区都有对应同一个键的累加器, 就需要使用用户提供的 mergeCombiners() 方法将各个分区
    的结果进行合并。
    3. 需求:创建一个 pairRDD,根据 key 计算每种 key 的均值。( 先计算每个 key 出现的次数
    以及可以对应值的总和,再相除得到结果)
     val input = sc.parallelize(Array(("a", 88), ("b", 95), ("a", 91), ("b", 93), ("a", 95),("b", 98)),2)
     val combine = input.combineByKey((_,1),(acc:(Int,Int),v)=>(acc._1+v,acc._2+1),(acc1:(Int,Int),acc2:(Int,Int))=>(acc1._1+acc2._1,acc1._2+acc2._2))
     combine.collect()
     res5: Array[(String, (Int, Int))] = Array((b,(286,3)), (a,(274,3)))
     val resoult = combine.map{case (key,value) =>(key,value._1/value._2.toDouble)}
     result.collect()
     res33: Array[(String, Double)] = Array((b,95.33333333333333),(a,91.33333333333333))
    
    1. sortByKey([ascending],[numTasks])案例
    作用:在一个(K,v)的RDD上调用,K必须实现ordered接口,返回一个按照key进行排序的(K,V)的RDD
    需求:创建一个pairRDD,按照key的正序和倒叙进行排序
    val rdd = sc.parallelize(Array((3,"aa"),(6,"cc"),(2,"bb"),(1,"dd")))
    rdd.sortByKey(true).collect()
    res9: Array[(Int, String)] = Array((1,dd), (2,bb), (3,aa), (6,cc))
    
    1. mapValues案例
    1. 针对于(K,V)形式的类型只对 V 进行操作
    2. 需求:创建一个 pairRDD,并将 value 添加字符串"|||"
    val rdd3 = sc.parallelize(Array((1,"a"),(1,"d"),(2,"b"),(3,"c")))
    rdd3.mapValues(_+"|||").collect()
    res26: Array[(Int, String)] = Array((1,a|||), (1,d|||), (2,b|||), (3,c|||))
    
    1. cogroup(otherDataset,[numTasks])案例
    作用:在类型为(K,V)和(K,W)的 RDD 上调用, 返回一个(K,(Iterable<V>,Iterable<W>))类
    型的 RDD
    需求:创建两个 pairRDD,并将 key 相同的数据聚合到一个迭代器。
    val rdd = sc.parallelize(Array((1,"a"),(2,"b"),(3,"c")))
    val rdd1 = sc.parallelize(Array((1,4),(2,5),(3,6)))
    rdd.cogroup(rdd1).collect()
    res14: Array[(Int, (Iterable[String], Iterable[Int]))] =Array((1,(CompactBuffer(a),CompactBuffer(4))), (2,(CompactBuffer(b),CompactBuffer(5))),(3,(CompactBuffer(c),CompactBuffer(6))))
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值