文章目录
- 转化操作
- Transformer算子概念
- 单RDD转换函数
- 多RDD转换函数
- map与flatmap
转化操作
由于spark的惰性计算特性,RDD只有在第一次行动操作中被用到时才会真正进行计算,因此我打算将文章内容分为"转化操作"和"行动操作"两部分,同时因为pair RDD(RDD中的元素是键值对)的部分api较为特殊
Transformer算子概念
RDD的操作算子分为两类:
- Transformation。用来对RDD进行转化,这个操作时延迟执行的(或者说是 Lazy 的);返回一个新的RDD
- Action。用来触发RDD的计算;得到相关计算结果 或者 将结果保存的外部系统 中;返回结果int、double、集合(不会返回新的RDD)
每一次 Transformation 操作都会产生新的RDD,供给下一个“转换”使用; 转换得到的RDD是惰性求值的。也就是说,整个转换过程只是记录了转换的轨迹, 并不会发生真正的计算,只有遇到 Action 操作时,才会发生真正的计算,开始从血 缘关系(lineage)源头开始,进行物理的转换操作;
单RDD转换函数
对数据rdd{1,2,3,3}进行RDD转换
函数 | 举例 | 运行效果 | 解释说明 |
map | rdd.map(x=>x+2) | {3,4,5,5} | 对RDD中每一个元素进行操作,对每个元素都+2 |
flatMap | rdd.flatMap(x=>x.to(3)) | {1,2,3,2,3,3,3} | 遍历当前每个元素,然后生成从当前元素到3的新RDD集合([当前元素,3]),通常用于切分单词 |
filter | rdd.filter(x=>x!=3) | {1,2} | 过滤RDD中不等于3的元素 |
distinct | rdd.distinct() | {1,2,3} | 对RDD去重 |
sample | rdd1.sample(false,0.5) | 随机 | 随机数生成RDD子数据集 |
map()函数
val testList = List(1, 2, 3, 3)
val testRdd = sc.parallelize(testList)
testRdd.map(x => x + 2).foreach(x => print(s"$x "))
// 输出:3 4 5 5
多RDD转换函数
对数据rdd1{1,2,3}和rdd2{2,4,6}进行RDD转换
函数 | 举例 | 运行结果 | 解释说明 |
union | rdd1.union(rdd2) | {1,2,3,2,4,6} | rdd1返回两个RDD的合并,不去重 |
intersection | rdd1.intersection(rdd2) | {2} | rdd1返回两个RDD的交集,去重 |
subtract | rdd1.subtract(rdd2) | {1,3} | 与intersection函数类似,rdd1返回在rdd1中出现,在rdd2中没有出现的元素,不去重(即移除rdd2的内容,通常用于移除训练数据) |
cartesian | rdd1.cartesian(rdd2) | {(1,2),(1,4),(1,6),(2,2),(2,4),(2,6),(3,2),(3,4),(3,6)} | 求笛卡尔积,对两个RDD数据进行笛卡尔计算,返回(T,U)Pair模板类型的RDD数据 |
unon()函数
相当于集合运算的并集,生成一个包含两个RDD中所有元素的RDD,要求两个RDD的元素类型相同
val testList1 = List(1, 2, 3)
val testList2 = List(2, 4, 6)
val testRdd1 = sc.parallelize(testList1)
val testRdd2 = sc.parallelize(testList2)
testRdd1.union(testRdd2).foreach(ele => print(s"$ele "))
// 输出:1 2 3 2 4 6
map与flatmap
下图说明了map和flatMap的区别,flatMapRDD中是一个个迭代器中的具体元素,但是map中是一个个迭代器。