Spark RDD 常用算子实例解析

一、转换算子 Transformation(lazy)

对于转换操作,RDD的所有转换都不会直接计算结果。 Spark仅记录作用于RDD上的转换操作逻辑,当遇到动作算子( Action)时才会进行真正计算。

RDD常见转换算子如下表:

Transformation 描述
map(func) 通过函数func作用于 源 RDD中 的每个元素,返回一个新的 RDD
filter(func) 选择源RDD中的使得函数 func为 true的元素,返回一个新的 RDD
flatMap(func) 与map类似,但是每个输入项可以映射到 0或多个输出项 (因此 func应该返回一个 Seq,而不是单个项 )
mapPartitions(func) 与map类似,但是在 RDD的每个分区上单独运行,所以 func在类型为 T的 RDD上运行时 必须是类型 Iterator<T> => Iterator<U>
mapPartitionsWithIndex(func) 与mapPartitions类似,但为 func多提供一个分区编号 ,所以 func类型为:(Int, Iterator<T>) => Iterator<U>
sample(withReplacement, fraction, seed) 使用给定的随机数生成器种子对数据的一部分进行采样
union(otherDataset) 返回一个新数据集,该数据集包含源数据集中的元素和参数的并集
intersection(otherDataset) 返回一个新的RDD,其中包含源数据集中的元素和参数的交集
distinct([numPartitions])) 返回包含源数据集的不同元素的新数据集
groupByKey([numPartitions]) 当调用一个(K, V)对的数据集时,返回一个 (K,Iterable<V>)对的数据集
aggregateByKey(zeroValue)(seqOp,combOp,[numPartitions]) seqOp操作会聚合各分区中的元素,然后combOp操作把所有分区的聚合结果再次聚合,两个操作的初始值都是 zeroValue. seqOp的操作是遍历分区中的所有元素 (T),第一个 T跟 zeroValue做操作,结果再作为与第二个 T做操作的 zeroValue,直到遍历完整个分区。 combOp操作是把各分区聚合的结果,再聚合
sortByKey([ascending],[numPartitions]) 根据key进行排序,默认为升序 ascending: Boolean = true
join(otherDataset,[numPartitions]) 当在类型(K, V)和 (K, W)的数据集上调用时,返回一个 (K (V, W))对的数据集,其中包含每个键的所有对元素。外部连接由 leftOuterJoin、 rightOuterJoin和 fullOuterJoin支持
cogroup(otherDataset,[numPartitions]) 当调用类型(K, V)和 (K, W)的数据集时,返回一个 (K(Iterable Iterable))元组的数据集。这个操作也称为groupWith
cartesian(otherDataset) 在类型为T和 U的数据集上调用时,返回一个 (T, U)对 (所有对元素 )的数据集
pipe(command, [envVars]) 通过shell命令 (例如 Perl或 bash脚本 )对 RDD的每个分区进行管道传输。将 RDD元素写入进程的stdin,并将其输出到 stdout的行作为字符串 RDD返回
coalesce(numPartitions) 将RDD中的分区数量减少到 numpartition
repartition(numPartitions) 随机地重新Shuffle RDD中的数据,以创建更多或更少的分区,并在它们之间进行平衡

二、动作算子 Actions(non-lazy)

Action 描述
reduce(func) 使用函数func(它接受两个参数并返回一个 )聚合数据集的元素
collect() 在驱动程序Driver 中以数组的形式返回数据集的所有元素
count() 返回数据集中元素的数量
first() 返回数据集的第一个元素(类似于 take(1))
take(n) 返回一个包含数据集前n个元素的数组
takeSample(withReplacement, num, [seed]) 返回一个数组,其中包含数据集的随机num元素样本,可以替换,也可以不替换,可以预先指定随机数生成器种子
takeOrdered(n, [ordering]) 使用RDD的自然顺序或自定义比较器返回 RDD的前n个元素
saveAsTextFile(path) 将数据集的元素作为文本文件(或文本文件集 )写入本地文件系统、 HDFS或任何其他 hadoop支持的文件系统的给定目录中。 Spark将对每个元素调用 toString,将其转换为文件中的一行文本
saveAsSequenceFile(path) 将数据集的元素作为Hadoop SequenceFile写入本地文件系统、 HDFS或任何其他 Hadoop支持的文件系统的给定路径中。这在实现 Hadoop的可写接口的键值对的 RDDs上是可用的。在 Scala中,它也可用于隐式转换为可写的类型 (Spark包括对Int、 Double、 String等基本类型的转换 )
saveAsObjectFile(path) 使用Java序列化以简单的格式编写数据集的元素,然后可以使用 SparkContext.objectFile()加载这些元素
countByKey() 仅在类型(K, V)的 RDDs上可用。返回 (K, Int)对的Map表示 每个键的计数
foreach(func) 对数据集的每个元素运行函数func

三、实例解析

map(func)

通过函数func作用于源RDD中的每个元素,返回一个新的RDD

示例:

object MapDemo extends App {
  //创建一个spark context对象
  val conf: SparkConf = new SparkConf().setMaster("local[6]").setAppName("sparkTest6")
  val sc: SparkContext = SparkContext.getOrCreate(conf)
  //创建一个RDD
  val a: RDD[Int] = sc.parallelize(1 to 10)
  a.collect().foreach(println)

  //TODO: map 对前一个rdd里面传过来的数据,每一个元素做一个操作
  private val b: RDD[Int] = a.map(x=>x*2)   //简写a.map(_*2)
  println("----------分割线-----------")
  b.collect().foreach(println)

  //TODO: 使用map将普通RDD转换成pairRDD
  private val c: RDD[(Int, Int)] = a.map(x=>(x,1))
  println("----------分割线-----------")
  println(c.collect().mkString("--"))

  sc.stop()
}
/*控制台打印结果
1
2
3
4
5
6
7
8
9
10
----------分割线-----------
2
4
6
8
10
12
14
16
18
20
(1,1)--(2,1)--(3,1)--(4,1)--(5,1)--(6,1)--(7,1)--(8,1)--(9,1)--(10,1)
*/

filter(func)

选择源RDD中的使得函数 func为 true的元素,返回一个新的 RDD

示例:

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object FilterRDD extends App {
  //创建一个spark context对象
  val conf: SparkConf = new SparkConf().setMaster("local[6]").setAppName("sparkTest6")
  val sc: SparkContext = SparkContext.getOrCreate(conf)
  //创建一个RDD
  val a: RDD[Int] = sc.parallelize(1 to 10)
  //TODO:过滤满足a中元素能被2整除则转化为RDD b
  private val b: RDD[Int] = a.filter(x=>x%2==0)
  println(b.collect().mkString("  "))

  sc.stop()
}
//控制台打印结果:2  4  6  8  10

flatMap(func)

与map类似,但是每个输入项可以映射到 0或多个输出项 (因此 func应该返回一个 Seq,而不是单个项 )

示例:

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object Demo extends App {
  //创建一个spark context对象
  val conf: SparkConf = new SparkConf().setMaster("local").setAppName("sparkTest")
  val sc: SparkContext = SparkContext.getOrCreate(conf)
  private val rdd1: RDD[String] = sc.parallelize(Array("hello java","hello scala","hello python"))
  private val rdd2: RDD[String] = rdd1.flatMap(x=>x.split(" "))
  rdd2.collect().foreach(println)
}
/*
hello
java
hello
scala
hello
python
*/

mapPartitions(func)

与map类似,但是在 RDD的每个分区上单独运行,所以 func在类型为 T的 RDD上运行时 必须是类型 Iterato<T> => Iterator<U>

示例:

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.rdd.RDD

object MapPartitionsDemo extends App {
  //创建一个spark context对象
  val conf: SparkConf = new SparkConf().setMaster("local[6]").setAppName("sparkTest6")
  val sc: SparkContext = SparkContext.getOrCreate(conf)

  val a: RDD[Int] = sc.parallelize(1 to 10)
  //TODO: map 对前一个rdd里面传过来的数据,每一个元素做一个操作
  val b: RDD[Int] = a.map(x=>x*2)
   b.collect().foreach(println)
  println("---------分割线------------")
  //TODO:mapPartitions每次处理一个分区的数据
  private val rdd2: RDD[Int] = a.mapPartitions(x=>x.map(_*2))
  println(rdd2.collect().mkString(" "))

  sc.stop()
}
/*
2
4
6
8
10
12
14
16
18
20
---------分割线------------
2 4 6 8 10 12 14 16 18 20
*/

mapPartitionsWithIndex(func)

与mapPartitions类似,但为 func多提供一个分区编号 ,所以 func类型为:(Int, Iterator<T>) => Iterator<U>

示例:


sample(withReplacement, fraction, seed)

使用给定的随机数生成器种子对数据的一部分进行采样

示例:


union(otherDataset)

返回一个新数据集,该数据集包含源数据集中的元素和参数的并集

示例:


intersection(otherDataset)

返回一个新的RDD,其中包含源数据集中的元素和参数的交集

示例:


distinct([numPartitions]))

返回包含源数据集的不同元素的新数据集

示例:


groupByKey([numPartitions])

当调用一个(K, V)对的数据集时,返回一个 (K,Iterable)对的数据集

示例:


aggregateByKey(zeroValue)(seqOp,combOp,[numPartitions])

seqOp操作会聚合各分区中的元素,然后combOp操作把所有分区的聚合结果再次聚合,两个操作的初始值都是 zeroValue. seqOp的操作是遍历分区中的所有元素 (T),第一个 T跟 zeroValue做操作,结果再作为与第二个 T做操作的 zeroValue,直到遍历完整个分区。 combOp操作是把各分区聚合的结果,再聚合

示例:


sortByKey([ascending],[numPartitions])

根据key进行排序,默认为升序 ascending: Boolean = true

示例:


join(otherDataset,[numPartitions])

当在类型(K, V)和 (K, W)的数据集上调用时,返回一个 (K (V, W))对的数据集,其中包含每个键的所有对元素。外部连接由 leftOuterJoin、 rightOuterJoin和 fullOuterJoin支持

示例:


cogroup(otherDataset,[numPartitions])

当调用类型(K, V)和 (K, W)的数据集时,返回一个 (K(Iterable Iterable))元组的数据集。这个操作也称为groupWith

示例:


cartesian(otherDataset)

在类型为T和 U的数据集上调用时,返回一个 (T, U)对 (所有对元素 )的数据集

示例:


pipe(command, [envVars])

通过shell命令 (例如 Perl或 bash脚本 )对 RDD的每个分区进行管道传输。将 RDD元素写入进程的stdin,并将其输出到 stdout的行作为字符串 RDD返回

示例:


coalesce(numPartitions)

将RDD中的分区数量减少到 numpartition

示例:


repartition(numPartitions)

随机地重新Shuffle RDD中的数据,以创建更多或更少的分区,并在它们之间进行平衡

示例:


reduce(func)

使用函数func(它接受两个参数并返回一个 )聚合数据集的元素

示例:


collect()

在驱动程序Driver 中以数组的形式返回数据集的所有元素

示例:


count()

返回数据集中元素的数量

示例:


first()

返回数据集的第一个元素(类似于 take(1))

示例:


take(n)

返回一个包含数据集前n个元素的数组

示例:


takeSample(withReplacement, num, [seed])

返回一个数组,其中包含数据集的随机num元素样本,可以替换,也可以不替换,可以预先指定随机数生成器种子

示例:


takeOrdered(n, [ordering])

使用RDD的自然顺序或自定义比较器返回 RDD的前n个元素

示例:


saveAsTextFile(path)

将数据集的元素作为文本文件(或文本文件集 )写入本地文件系统、 HDFS或任何其他 hadoop支持的文件系统的给定目录中。 Spark将对每个元素调用 toString,将其转换为文件中的一行文本

示例:


saveAsSequenceFile(path)

将数据集的元素作为Hadoop SequenceFile写入本地文件系统、 HDFS或任何其他 Hadoop支持的文件系统的给定路径中。这在实现 Hadoop的可

示例:


saveAsObjectFile(path)

使用Java序列化以简单的格式编写数据集的元素,然后可以使用 SparkContext.objectFile()加载这些元素

示例:


countByKey()

仅在类型(K, V)的 RDDs上可用。返回 (K, Int)对的Map表示 每个键的计数

示例:


foreach(func)

对数据集的每个元素运行函数func

示例:

猜你喜欢

转载自blog.csdn.net/and52696686/article/details/107822714