1:map函数把一个普通的RDD转化为pair RDD
var lines = sc.parallelize(List("i love you"))
val pairs = lines.map(x=>(x,1))
pairs.foreach(println)
(i love you,1)
2:Pai RDDr的转化操作
由于pair RDD中包含二元组,所以需要传递函数应当操作二元组而不是独立的元素,假设键值对集合为{(1,2),(3,4),(3,6)}
val rdd = sc.parallelize(List((1,2),(3,4),(3,6)))
-
rdd.reduceByKey(func):合并具有相同key的value值
val result = rdd.reduceByKey((x,y)=>x+y)
result.foreach(println)
(1,2)
(3,10)
-
rdd.groupByKey():对具有相同键的进行分组 [数据分组]
val result = rdd.groupByKey()
result.foreach(println)
(3,CompactBuffer(4, 6))
(1,CompactBuffer(2))
-
rdd.mapValues(func):对pairRDD中的每个值应用func 键不改变
val result = rdd.mapValues(x=>x+1)
result.foreach(println)
(1,3)
(3,5)
(3,7)
-
rdd.flatMapValues(func):类似于mapValues,返回的是迭代器函数
val result = rdd.flatMapValues(x=>(x to 5))
result.foreach(println)
(3,4)
(3,5)
(1,2)
(1,3)
(1,4)
(1,5)
-
rdd.keys:返回一个仅包含键的RDD
val result = rdd.keys
result.foreach(println)
3
1
3
-
rdd.values:返回一个仅包含value的RDD
val result = rdd.values
result.foreach(println)
2
4
6
-
rdd.sortByKey():返回一个根据键排序的RDD
数据排序,可以通过接受ascending的参数表示我们是否想要结果按升序排序(默认是true)
val result = rdd.sortByKey().collect()
// val result = rdd.sortByKey(ascending=false).collect()
result.foreach(println)
(1,2)
(3,4)
(3,6)
3:针对两个pair RDD 的转化操作
假设: rdd={(1,2),(3,4),(3,6)} other={(3,9)}
val rdd = sc.parallelize(List((1,2),(3,4),(3,6)))
val other = sc.parallelize(List((3,9)))
-
rdd.subtractByKey( other ):删除掉RDD中与other RDD中键相同的元素
val result = rdd.subtractByKey(other)
result.foreach(println)
(1,2)
-
rdd.join( other ):对两个RDD进行内连接
val result = rdd.join(other)
result.foreach(println)
(3,(4,9))
(3,(6,9))
-
rdd.rightOuterJoin(other):确保第二个RDD的键必须存在(右外连接)
val result = rdd.rightOuterJoin(other)
result.foreach(println)
(3,(Some(4),9))
(3,(Some(6),9))
-
rdd.leftOuterJoin(other):确保第一个RDD的键必须存在(左外连接)
val result = rdd.leftOuterJoin(other)
result.foreach(println)
(3,(4,Some(9)))
(3,(6,Some(9)))
(1,(2,None))
-
rdd.cogroup(other),将有两个rdd中拥有相同键的数据分组
val result = rdd.cogroup(other)
result.foreach(println)
(1,(CompactBuffer(2),CompactBuffer()))
(3,(CompactBuffer(4, 6),CompactBuffer(9)))
4:过滤操作
这里假设 rdd={(1,2),(3,4),(3,6)}
val rdd = sc.parallelize(List((1,2),(3,4),(3,6)))
> 对value做控制,key不加限制条件
val result = rdd.filter{case(x,y)=>y<=4}
result.foreach(println)
(1,2)
(3,4)
> 对key做控制,value不控制
val result = rdd.filter{case(x,y)=>x<3}
result.foreach(println)
(1,2)
5:聚合操作
使用 mapValues() 和 reduceByKey() 计算每个键对应的平均值
val rdd = sc.parallelize(List(Tuple2("panda",0),Tuple2("pink",3),Tuple2("pirate",3),Tuple2("panda",1),Tuple2("pink",4)))
val result = rdd.mapValues(x=>(x,1)).reduceByKey((x,y)=>(x._1+y._1,x._2+y._2))
result.foreach(println)
(pirate,(3,1))
(panda,(1,2))
(pink,(7,2))
-
分布式单词计数问题(使用flatMap() 来生成以单词为键,以数字1为值的pair RDD)
val rdd = sc.parallelize(List("i am thinkgamer, i love cyan"))
val words = rdd.flatMap(line => line.split(" "))
val result = words.map(x=>(x,1)).reduceByKey((x,y) => x+y)
result.foreach(println)
(cyan,1)
(love,1)
(thinkgamer,,1)
(am,1)
(i,2)
-
分布式单词计数问题(使用countByValue更快的实现单词计数)
val rdd = sc.parallelize(List("i am thinkgamer, i love cyan"))
val result = rdd.flatMap(x=>x.split(" ")).countByValue()
result.foreach(println)
(am,1)
(thinkgamer,,1)
(i,2)
(love,1)
(cyan,1)
6:pair RDD的行动操作
和转化操作一样,所有基础RDD支持的传统行动操作也都在pair RDD上可用,pair RDD提供了一些额外的行动操作,可以让我们充分利用数据的键值对特性,如下
以键值对集合{(1,2),(3,4),(3,6)}为例
函数名 | 描述 | 示例 | 结果 |
countByKey | 对每个键对应的元素分别计数 | rdd.countByKey() | {(1,1),(3,2)} |
collectAsMap() | 将结果以映射表的形式返回,以便查询 | rdd.collectAsMap() | Map{(1,2),(3,4),(3,6)} |
lookup(key) | 返回给定键对应的所有值 | rdd.lookup(3) | [4,6] |
转载: https://blog.csdn.net/gamer_gyt/article/details/51747783