1.map算子
- 定义: map(fun)函数
- 解释: 将RDD的每一个元素通过fun函数计算得到一个新的结果,新的结果我们会组合成为一个新的RDD
- 特别注意:一对一场景下,RDD的每一条数据对应新的RDD的中一条数据
- 案例:
| def mapOper(sc: SparkContext): Unit = { |
| println("----------------map1开始------------------") |
| val rdd = sc.makeRDD(Array(1, 2, 3, 4, 5, 0), 1) |
| val map = rdd.map(_ * 3) |
| map.foreach(println(_)) |
| println("----------------map1结束------------------") |
| |
| println("----------------map2开始------------------") |
| val rdd2 = sc.makeRDD(Array("hbase", "flink", "kafka")) |
| val word = rdd2.map((_, 1)) |
| word.foreach(println(_)) |
| println("----------------map2结束------------------") |
| } |
2.filter过滤算子
- 定义: filter(fun)算子
- 解释:将RDD中每一个元素通过fun函数计算得到一个boolean类型的返回值,如果返回值为true保留数据
- 特别注意:如果返回值为false,那么数据就舍弃 得到的新的RDD的类型和旧的RDD类型一样的
- 案例:
| def filterOper(sc: SparkContext): Unit = { |
| println("----------------filter开始------------------") |
| |
| |
| |
| val rdd = sc.makeRDD(1 to 10) |
| val filter = rdd.filter((num: Int) => { |
| if (num % 2 == 0) { |
| true |
| } else { |
| false |
| } |
| }) |
| filter.foreach(println(_)) |
| println("----------------filter结束------------------") |
| } |
3.flatMap压扁算子
- 定义:flatMap(fun)算子
- 解释:原先的RDD一条数据经过flatMap算子操作返回一个集合数据,集合数据中每一条数据就是新的RDD中的数据
- 特别注意:一对多
- 案例:
| def flatMap(sc: SparkContext): Unit = { |
| println("----------------flatMap开始------------------") |
| val rdd = sc.makeRDD(Array("i am people", "dog is an animal")) |
| val flatmap = rdd.flatMap((str: String) => { |
| val word: Array[String] = str.split(" ") |
| word |
| }) |
| flatmap.foreach(println(_)) |
| println("----------------flatMap结束------------------") |
| } |
|
区别 |
map |
输入一条数据,就输出一条数据 |
flatMap |
输入一条数据,按一定的规则输出多条数据 |
4.mapPartitions
- 定义:mapPartitions(fun)算子
- 解释:和map算子函数含义一致,都是一个分区数据经过fun函数得到一个新的分区数据结果,新的结果组成新的RDD
- 案例:
| def mapPartitionsOper(sc: SparkContext): Unit = { |
| println("----------------mapPartitions开始------------------") |
| val rdd: RDD[Int] = sc.makeRDD(Array(1, 2, 3, 4, 5, 6, 7, 8), 5) |
| val mapPartitions = rdd.mapPartitions((list: Iterator[Int]) => { |
| val listBuffer: ListBuffer[Int] = ListBuffer() |
| for (num <- list) { |
| println(s"处理的分区数据是 $num") |
| listBuffer.append(num * 3) |
| } |
| listBuffer.iterator |
| }) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| mapPartitions.foreach(println(_)) |
| println("----------------mapPartitions结束------------------") |
| } |
|
区别 |
map |
每条数据都操作一次 |
mapPartitions |
对每一分区数据操作一次 |
5.mapPartitionsWithIndex
- 定义:mapPartitionsWithIndex(fun)算子
- 解释:一次处理一个分区的数据,最后返回一个迭代器,附带传入一个分区索引
fun函数输入参数类型是一个2元组(Int,Iterator[T])=>Iterator[U] :RDD[U]
- 案例:
| def mapPartitionsWithIndexOper(sc: SparkContext): Unit = { |
| println("----------------mapPartitionsWithIndex开始------------------") |
| val rdd: RDD[Int] = sc.makeRDD(Array(1, 2, 3, 4, 5, 6, 7, 8), 5) |
| val mapPartitionsWithIndex: RDD[Int] = rdd.mapPartitionsWithIndex((index: Int, iterator: Iterator[Int]) => { |
| val listBuffer: ListBuffer[Int] = ListBuffer() |
| for (num <- iterator) { |
| println(s"分区为 $index , 分区的数据为 $num ") |
| listBuffer.append(num) |
| } |
| listBuffer.iterator |
| }) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| mapPartitionsWithIndex.foreach(println((_))) |
| println("----------------mapPartitionsWithIndex结束------------------") |
| } |
总结
如果要实现将一个RDD数据集中每一条数据转换成为一个新的RDD数据集中记录,
可以使用map、mapPartitions、mapPartitiosWithIndex三种方式实现
一般我们建议使用mapPartitions、mapPartitiosWithIndex 这样的效率比较高点
6.sample
- 定义:sample(withReplacement, fraction, seed):RDD[T] 抽样算子
withReplacement:Boolean 是否放回抽样 true放回抽样,false代表不放回抽象
fraction:Double 如果是放回抽样 整数代表同一个数据期望被抽中几次 如果是不放回抽样,0-1之间的小数,代表的抽取比例
seed 种子 不用写(默认值) 抽样底层有算法,
- 解释:抽样一部分数据进行处理分析(每个分区都会抽取数据)
- 案例:
| def sampleOper(sc: SparkContext): Unit = { |
| println("----------------sample开始------------------") |
| val rdd: RDD[Int] = sc.makeRDD(Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3), 4) |
| val sample = rdd.sample(false, 0.5) |
| val mapPartitionsWithIndex: RDD[Int] = sample.mapPartitionsWithIndex((index: Int, data: Iterator[Int]) => { |
| println(s"分区为 $index , 数据为 ${data.mkString("=")}") |
| data |
| }) |
| |
| mapPartitionsWithIndex.count() |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| println("----------------sample结束------------------") |
| } |
7.union(另外一个RDD)
- 定义:两个RDD求一个并集返回一个新的RDD 两个RDD的类型必须保持一致
- 分区:两个RDD的分区数之和
- 案例:
| def unionOper(sc: SparkContext): Unit = { |
| println("----------------union开始------------------") |
| val rdd = sc.makeRDD(Array(1, 2, 3, 4, 5, 6, 7, 8, 9), 3) |
| val rdd1 = sc.makeRDD(Array(1, 12, 13, 14), 2) |
| val rdd2 = rdd.union(rdd1) |
| println("union后的分区数:" + rdd2.getNumPartitions) |
| rdd2.foreach((num: Int)=>print(num + ",")) |
| println("----------------union结束------------------") |
| } |
8. intersection(另外一个RDD) 交集 两个RDD类型一致
| def intersectionOper(sc: SparkContext): Unit = { |
| println("----------------intersection开始------------------") |
| val rdd = sc.makeRDD(Array(1, 2, 3, 4, 5, 6, 7, 8, 9), 3) |
| val rdd1 = sc.makeRDD(Array(1, 12, 13, 14), 2) |
| val rdd2 = rdd.intersection(rdd1) |
| println("intersection交集后的分区数:" + rdd2.getNumPartitions) |
| rdd2.foreach((num: Int)=>print(num + ",")) |
| println("----------------intersection结束------------------") |
| } |
9.distinct(numPartitions=默认值) 对rdd进行去重
| def distinctOper(sc: SparkContext): Unit = { |
| println("----------------distinct开始------------------") |
| val rdd = sc.makeRDD(Array(1, 1, 1, 1, 5, 6, 7, 8, 9), 3) |
| val rdd2 = rdd.distinct() |
| println("去重后的分区数:" + rdd2.getNumPartitions) |
| rdd2.foreach(println(_)) |
| println("----------------distinct结束------------------") |
| } |
10.repartition(numPartitios) 对RDD数据集指定的分区数重新分区
| def repartitionOper(sc: SparkContext): Unit = { |
| println("----------------repartition开始------------------") |
| val rdd = sc.makeRDD(Array(1, 1, 1, 1, 5, 6, 7, 8, 9), 10) |
| println(rdd.getNumPartitions) |
| val rdd2 = rdd.repartition(2) |
| println(rdd2.getNumPartitions) |
| println("----------------repartition结束------------------") |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?