Scala 集合操作(有助于理解RDD的操作)
* 映射
List(1,7,2,9).map(_.toFloat)
#res7: List[Float] = List(1.0, 7.0, 2.0, 9.0)
List(1,7,2,9).map( x => ( 1 to x) )
#res:=List(Range(1), Range(1, 2, 3, 4, 5, 6, 7), Range(1, 2), Range(1, 2, 3, 4, 5, 6, 7, 8, 9))
* 化简
List(1,7,2,9).reduceLeft(_-_)
#原理: ((1-7)-2)-9 = -17
* 折叠
List(1,7,2,9).foldLeft(0)(_-_)
#原理: 0-1-7-2-9 = -19
* 扫描(将折叠和映射操作结合一起,得到包含的所有中间结果)
List(1,7,2,9).scanLeft(0)(_+_)
#res6: List[Int] = List(0, 1, 8, 10, 19)
一 基本RDD转换操作
1)RDD本身操作
map 将RDD中类型为T的元素一对一的映射为类型U的元素
distinct 返回rdd中所有不一样的元素
flatMap 一对多的转换
* 程序
var rdd = sc.makeRDD(1 to 5,1)
val mapRDD = rdd.map( x => (x + 1) )
#res1: Array[Int] = Array(2, 3, 4, 5, 6)
var flatRDD = rdd.flatMap(x => (1 to x))
#res2: Array[Int] = Array(1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5)
var distinctRDD = flatRDD.distinct()
#res3: Array[Int] = Array(4, 1, 3, 5, 2)
2)RDD与RDD之间的操作
union 两个RDD的并集
Intersection 两个集合的交集
Subtract 就补集
(val result = A.subtract(B),result包含在A且不在B中的元素)
zip 将两个RDD组合成Key/value的形式
zipWithIndex 将RDD中的元素和这个元素的ID组合成key/value对
zipWithUniqueId 和分区索引组合成key/value形式
* 程序
var rdd1 = sc.makeRDD( 1 to 3, 1)
var rdd2 = sc.makeRDD( 2 to 4, 1)
val unionRDD = rdd1.union(rdd2)
#res4: Array[Int] = Array(1, 2, 3, 2, 3, 4)
var intersectionRDD = rdd1.intersection(rdd2)
#res5: Array[Int] = Array(3, 2)
var subtract = rdd1.subtract(rdd2)
#res6: Array[Int] = Array(1)
var zipRDD = rdd1.zip(rdd2)
#res9: Array[(Int, Int)] = Array((1,2), (2,3), (3,4))
var zipWithIndex = rdd2.zipWithIndex()
#res10: Array[(Int, Long)] = Array((2,0), (3,1), (4,2))
二 键值RDD转换操作
* value操作
mapValues: 对map中的value进行map操作
flatMapValues:对map中的value进行flatMap操作
#程序
var rdd = sc.parallelize(Array((1,1),(1,2),(2,1),(3,1)),1)
var mapValuesRDD = rdd.mapValues( x => x + 1 )
#res12: Array[(Int, Int)] = Array((1,2), (1,3), (2,2), (3,2))
var flatMapValuesRDD = rdd.flatMapValues( x => Seq(x,"a") )
#res13: Array[(Int, Any)] = Array((1,1), (1,a), (1,2), (1,a), (2,1), (2,a), (3,1), (3,a))
*key 操作
1 combine操作
combineByKey :将RDD[K,V]转[K,C]
foldByKey
reduceByKey
groupByKey
程序
var pairs = sc.parallelize(Array((1,1),(1,2),(1,3),(1,1),(2,1)),2)
var foldByKeyRDD = pairs.foldByKey(0)(_+_)
#res16: Array[(Int, Int)] = Array((2,1), (1,7))
val reduceByKeyRDD = pairs.reduceByKey(_-_)
#res17: Array[(Int, Int)] = Array((2,1), (1,-3))
var groupByKeyRDD = pairs.groupByKey()
#res18: Array[(Int, Iterable[Int])] = Array((2,CompactBuffer(1)), (1,CompactBuffer(1, 2, 3, 1)))
* join操作(RDD与RDD之间的操作)
cogroup :根据key将两个rdd平行合并(类似union)
Join: 内连接
leftOutJoin: 左外连接左边的集合都要保留
rightOutJoin: 右连接右边的集合都要保留
subtractByKey: 通过key求补集
程序
var rdd1 = sc.parallelize(Array((1,1),(1,2),(2,1),(3,1)),1)
var rdd2 = sc.parallelize(Array((1,'x'),(2,'y'),(2,'z'),(4,'w')),1)
var cogroupRDD = rdd1.cogroup(rdd2)
#res19:Array[(Int,(Iterable[Int],Iterable[Char]))]=Array((4,(CompactBuffer(),CompactBuffer(w))),(1,(CompactBuffer(1,2),CompactBuffer(x))),(3,(CompactBuffer(1),CompactBuffer())), (2,(CompactBuffer(1),CompactBuffer(y, z))))
var joinRDD = rdd1.join(rdd2)
#res20: Array[(Int, (Int, Char))] = Array((1,(1,x)), (1,(2,x)), (2,(1,y)), (2,(1,z)))
val leftOuterJoinRDD = rdd1.leftOuterJoin(rdd2)
#res21: Array[(Int, (Int, Option[Char]))] = Array((1,(1,Some(x))), (1,(2,Some(x))), (3,(1,None)), (2,(1,Some(y))), (2,(1,Some(z))))
var subtracByKey = rdd1.subtractByKey(rdd2)
#res22: Array[(Int, Int)] = Array((3,1))
三 控制操作(可以将rdd持久化到不同层次的存储介质中)
Cache()
Persist()
Checkpoint() 将rdd持久化到HDFS中,和persist()不同会切断rdd之间的依赖关系,而persits依然保留rdd的依赖关系
四 行动操作(会触发一次spark的调度并返回相应的结果)
1) 集合标量行动操作
first : 返回RDD中的第一个元素
count: 返回RDD中元素的个数
Reduce: 对RDD中的元素进行二元计算,返回结果
take(3): 返回集合的前三个元素
top(3) 返回集合从大到小的前三个元素
takeOrder(3):返回值跟top(3)刚好互换
程序
var rdd = sc.makeRDD(1 to 10,1)
rdd.first
#res23: Int = 1
rdd.count
#res24: Long = 10
rdd.reduce(_-_)
#res25: Int = -53
rdd.top(3)
#res26: Array[Int] = Array(10, 9, 8)
rdd.take(3)
#res27: Array[Int] = Array(1, 2, 3)
rdd.takeOrdered(3)
#res30: Array[Int] = Array(1, 2, 3)
Aggregate(seqOp)(combOp)
*seqOp 将rdd每个分区中类型T元素聚合成类型为U的值
*combOp 将各个分区聚合起来的值合并在一起得到最终类型U的返回值
程序
var rdd = sc.makeRDD( 1 to 10, 3)
var aggregateResult = rdd.aggregate(0)(math.max(_,_))(_+_)
#res38: (Int, Int) = (1,3)
fold(initValue:T)(op)操作是aggregate的便利接口,其中op及是seqOp也是combOp操作
程序
var pairs = sc.parallelize(Array((1,1),(1,2),(1,3),(1,1),(2,1)),2)
var compareElement:((Int,Int),(Int,Int)) => (Int,Int) = (val1,val2) => {
| if(val1._2 >= val2._2){
| val1
| }else {
| val2
| }
| }
var foldResult = pairs.fold((0,0))(compareElement)
#res33: (Int, Int) = (1,3)
2)存储行动操作
saveAsTextFile(path:String)
saveAsHadoopFile...............