了解下Spark的函数API
一 . 创建RDD
1.普通数组创建RDD
val a = sc.parallelize(1to9,3)
这个含义是,生成 1 到 9 的9个数字,分成 3 个区来存储
2.普通文本文件创建RDD
val b = sc.textFile("README.md")
这个是读取文本文件来存储到RDD中,一行作为一条记录
二 函数
map
map是对RDD中的每个元素都执行一个指定的函数来产生一个新的RDD。 任何原RDD中的元素在新RDD中都有且只有一个元素与之对应。
val rdd = sc.parallelize(1 to 9, 3)
val rdd2 = rdd.map(x => x * 2)
rdd2.foreach(x => print(x + " "))
结果:
2 4 6
8 10 12
14 16 18
上一个map方法表示把原RDD的每一个元素乘以 2 得到新的RDD
mapValues
作用于有KV的RDD,基于原有的RDD,K 不变,V 做对应的计算,得到新的包含原有K和新V的RDD,和map一样是对每个元素都要执行,也是一对一
val rdd = sc.parallelize(List("DOG", "TIGER", "LION", "CAT"), 2)
val rdd2 = rdd.map(a => (a.length, a)).mapValues("x" + _ + "x")
rdd2.foreach(x => print(x + " "))
这里初始化一个RDD,2 个分区,第一个map函数得到KV格式的RDD,如(3,DOG),mapValues函数对V计算,那么新的V就是xDOGx
结果:
(3,xDOGx) (5,xTIGERx)
(4,xLIONx) (3,xCATx)
flatMap
与map类似,也是处理原RDD中的所有元素,生成一个新RDD
区别是原RDD中的一个元素经map处理后只能生成一个元素,而原RDD中的元素经flatMap处理后可生成多个元素来构建新RDD。
举例:对原RDD中的每个元素x产生y个元素(从x到5,全部的元素)
val rdd = sc.parallelize(1 to 5, 2)
val rdd2 = rdd.flatMap(x => x to 5)
rdd2.foreach(x => print(x + " "))
初始化一个RDD,存有1 2 3 4 5 ,五个元素2个区,flatMap函数表示将每个元素扩展开,该元素到5的所有元素
举个例子,如果x=2,那么经过flatMap处理过后返回 2 3 4 5
结果:
1 2 3 4 5 2 3 4 5
3 4 5 4 5 5
flatMapValues
与mapValues相似,每个一元素的V被输入函数映射为一系列的值,然后这些值再与原RDD中的K组成一系列新的KV对。
val rdd = sc.parallelize(List((1, 2), (3, 4), (3, 6)))
val rdd2 = rdd.flatMapValues(x => x.to(5))
rdd2.foreach(x => print(x + " "))
初始化一个原RDD,这里采用默认的一个分区
这里举个例子,原RDD要处理KV元素(1,2),经过flatMapValues把V扩展开为 2 3 4 5,再与原K组成新的KV对 (1,2) (1,3) (1,4) (1,5)
结果:
(1,2) (1,3) (1,4) (1,5) (3,4) (3,5)
reduce
reduce将RDD中元素两两传递给输入函数,同时产生一个新的值,新产生的值与RDD中下一个元素(第三个元素)再被传递给输入函数直到最后只有一个值为止。
val rdd = sc.parallelize(1 to 10)
val rdd2 = rdd.reduce((x, y) => x + y)
println(rdd2)
具体过程,RDD有1 2 3 4 5 6 7 8 9 10个元素, 这里 reduce((x,y)=>x+y) 等同为 reduce(_ + _)
1+2=3 3+3=6 6+4=10 10+5=15 15+6=21 21+7=28 28+8=36 36+9=45 45+10=55
结果:
55
reduceByKey
顾名思义,reduceByKey就是对元素为KV对的RDD中K相同的元素的V进行reduce
因此,K相同的多个元素的值V被reduce为一个值,然后与原RDD中的K组成一个新的KV对。
val rdd = sc.parallelize(List((1, 2), (3, 4), (3, 6)))
val rdd2 = rdd.reduceByKey((x, y) => x + y)
rdd2.foreach(x => print(x + " "))
这里表示对相同K的V做求和计算,如(3,4)和(3,6),这里K相同,V求和为10,组成一个新的KV对为(3,10), 这里 reduce((x,y)=>x+y) 等同为 reduce(_ + _)
结果:
(1,2) (3,10)
union
将两个RDD中的数据集进行合并,最终返回两个RDD的并集,若RDD中存在相同的元素也不会去重
val rdd = sc.parallelize(1.to(5))
val rdd1 = sc.parallelize(2 to 4)
val rdd2 = rdd.union(rdd1)
rdd2.foreach(x => print(x + " "))
println("分区个数:" + rdd2.partitions.size)
rdd是1 2 3 4 5,rdd1是2 3 4,两个RDD都为一个默认分区
注意:虽然合并为一个数据集RDD,但是合并后的RDD有两个分区,该操作后分区数=两个RDD分区数之和
最后一行代码是查看一个RDD的分区数
结果:
1 2 3 4 5
2 3 4
val rdd2 = rdd.intersection(rdd1)