官方文档上列举共有32种常见算子,包括Transformation的20种操作和Action的12种操作。
内容自己用心整理,看我的就够了
Transformation:
1.map
map的输入变换函数应用于RDD中所有元素,而mapPartitions应用于所有分区。区别于mapPartitions主要在于调用粒度不同。如parallelize(1 to 10, 3),map函数执行10次,而mapPartitions函数执行3次。
object TestTransformation {
def main(args: Array[String]): Unit = {
//0.先创建SparkContext对象
val conf = new SparkConf().setAppName("TestTransformation").setMaster("local")
val sc = new SparkContext(conf)
//1.创建RDD
val rdd: RDD[Int] = sc.parallelize(List(5,6,4,7,3,9,2,10,8))
//1.遍历RDD中每一个元素并进行操作 参数是一个处理RDD中数据的函数
val rdd2: RDD[Int] = rdd.map(_ * 2)
//行动算子 collect 将RDD中数据转换成一个集合进行存储
println(rdd2.collect().toBuffer)
2.filter
参数(function)
过滤操作,满足filter内function函数为true的RDD内所有元素组成一个新的数据集。如:filter(a == 1)。
3.flatMap
参数(function)
map是对RDD中元素逐一进行函数操作映射为另外一个RDD,而flatMap操作是将函数应用于RDD之中的每一个元素,将返回的迭代器的所有内容构成新的RDD。
flatMap与map区别在于map为“映射”,而flatMap“先映射,后扁平化”,map对每一次(func)都产生一个元素,返回一个对象,而flatMap多一步就是将所有对象合并为一个对象。
//3.遍历RDD中每一个元素并将元素进行扁平化处理
val rdd4 = sc.parallelize(Array("a b c","b c d"))
//得到集合中集合的效果 而非集合中存储数据
//val rdd5: RDD[Array[String]] = rdd4.map(_.split(" "))
val rdd5: RDD[String] = rdd4.flatMap(_.split(" "))
println(rdd5.collect().toBuffer)
4.mapPartitions
参数(function)
区于foreachPartition(属于Action,且无返回值),而mapPartitions可获取返回值。与map的区别前面已经提到过了,但由于单独运行于RDD的每个分区上(block),所以在一个类型为T的RDD上运行时,(function)必须是Iterator => Iterator类型的方法(入参)。
//遍历出集合中每一个元素并进行操作 //创建了一个rdd1,数据作用在3个分区上
val rdd1 =sc.parallelize(List(1,2,3,4,5,6),3)
/*
mapPartitions是对每一个分区中数据进行迭代(数据处理 操作)
f: Iterator[T] => Iterator[U] 第一个参数迭代器是对象[分区对象] preservesPartitioning: Boolean = false 默认值 是否保留父RDD的分区信息(此值不传
入)
mapPartitions 和 map算子 如果是一个分区遍历的效果是没有什么区别的
但是建议在实际开发中使用mapPartitions算子代替Map,可以加载数据的处理
ps:如果RDD中数据量过大比如10亿条,此时坚决不要使用mapPartitions进行数据遍历,可能会
出现OOM内存溢出 */
rdd1.mapPartitions(_.map(_*10))
//解释:第一个下滑线代表的是对应的分区即rdd有几个分区,下划线就会被执行多少次
//例如: 分区是3 --> 数据可能会被分为 1,2 一个分区 3,4 一个分区 5,6 一个分区 此时_ 代表的就是每一个分区对象
// 第二个下划线代表的是每一个分区内部的具体数据
//例如: 第一个下划线触发了第一个分区 得到数据是 1,2 第二个下划线就有相当于是 1*10 2*10
5.mapPartitionsWithIndex
参数(function)
与mapPartitions类似,但需要提供一个表示分区索引值的整型值作为参数,因此function必须是(int, Iterator)=>Iterator类型的。
//mapPartitionsWithIndex 是对rdd中每个分区的遍历操作
//本质操作和mapPartitions类似,只不过,可以更加具体的是对数据进行输出
/**
* f: (Int, Iterator[T]) => Iterator[U] 第一个参数是分区的迭代方式,迭代方式有两 个值Int是分区值(第几分区) Iterator代表的是分区内部具体的值
值不传
* preservesPartitioning: Boolean = false 是否保留父RDD的Partition信息 默认 */
val Iter = (index:Int,iter:Iterator[Int])=>{
iter.map(x => {"[partID"+index+",value"+x+"]"})
}
val rdd3: RDD[String] = rdd1.mapPartitionsWithIndex(Iter)
println(rdd3.collect.toList)
6.sample
参数(withReplacement, fraction, seed)
采样操作,用于从样本中取出部分数据。withReplacement是否放回,fraction采样比例,seed用于指定的随机数生成器的种子。(是否返回抽样分true和false,fraction取样比例为(0, 1]。seed种子为整型实数。)
//4.sample随机抽样
val rdd5_1 = sc.parallelize(1 to 10)
/**
* withReplacement: Boolean第一参数抽出数据是否返回 true为返回 f