【博学谷学习记录】超强总结,用心分享|Spark的RDD算子分类
创始人
2024-05-24 17:53:06
0

概念

RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,代表一个不可变、可分区、里面的元素可并行计算的集合,它是一种抽象的数据模型,本身并不存储数据,仅仅是一个数据传输的管道,作为使用者,只需要告知RDD,数据从哪里读,中间需要进行什么样的转换逻辑,以及最后需要将结果输出到什么位置即可,RDD启动后,会根据用户设置的规则,完成整个处理操作

分类

所有的RDD算子,共分为2大类

  1. Transformation(转换算子)
    1. 所有的转换算子执行后,都会返回一个新的RDD
    2. 所有转换算子是惰性的,不会立即执行,可以认为只是此时只是定义了RDD的计算规则
    3. 转换算子必须遇到动作算子都会触发执行
    4. 常见转换算子
      1. map, filter, flatMap, mapPartitions, mapPartitionsWithIndex
  2. Action(动作算子)
    1. 动作算子执行后,不会返回一个RDD,要么没有返回值,要么返回其它的
    2. 动作算子都是立即执行,一个动作算子会产生一个Jo任务,运行动作算子所依赖的所有RDD
    3. 常见动作算子
      1. collect, count, first, take, reduce

转换算子

值类型的算子

map算子
  • 格式:rdd.map(fn)
  • 说明:根据传入的函数,对数据进行一对一的转换操作,传入一行,返回一行
rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10])# 需求: 请对每一个元素进行 +1 返回
rdd_collect = rdd.map(lambda num: num + 1).collect()
print(rdd_collect)结果:
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

groupBy算子
  • 格式:rdd.groupBy(fn)
  • 说明:根据传入的函数对数据进行分组操作
rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10])# 需求: 请将数据分为奇数和偶数二部分
rdd_collect = rdd.groupBy(lambda num: 'o' if num % 2 == 0 else 'j').mapValues(list).collect()
print(rdd_collect)结果:[('j', [1, 3, 5, 7, 9]), ('o', [2, 4, 6, 8, 10])]

filter算子
  • 格式:rdd.filter(fn)
  • 说明:过滤算子, 可以根据函数中指定的过滤条件, 对数据进行过滤操作, 条件返回True表示保留, 返回False表示过滤掉
rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10])# 需求: 请将 <=3的数据过滤掉
rdd_collect = rdd.filter(lambda num: num > 3).collect()
print(rdd_collect)结果:[4, 5, 6, 7, 8, 9, 10]

flatMap算子
  • 格式:rdd.flatMap(fn)
  • 说明:在map算子的基础上, 在加入一个压扁的操作, 主要适用于一行中包含多个内容的操作, 实现一转多的操作
rdd = sc.parallelize(['张三 李四 王五 赵六','田七 周八 李九'])# 需求: 将其转换为一个个的姓名
rdd_collect = rdd.flatMap(lambda line: line.split()).collect()
print(rdd_collect)结果:['张三', '李四', '王五', '赵六', '田七', '周八', '李九']

双值类型的算子

union算子
  • 格式:rdd1.union(rdd2)
  • 说明:取两组数据的并集
rdd1 = sc.parallelize([3,1,5,7,9])
rdd2 = sc.parallelize([5,8,2,4,0])# 需求: 取两组数据的并集
rdd1.union(rdd2).collect()结果:[3, 1, 5, 7, 9, 5, 8, 2, 4, 0]# 去重操作: 
rdd1.union(rdd2).distinct().collect()结果:[8, 4, 0, 1, 5, 9, 2, 3, 7]

intersection算子
  • 格式:rdd1.intersection(rdd2)
  • 说明:取两组数据的交集
rdd1.intersection(rdd2).collect()结果:[5]

KV类型的算子

groupByKey算子:
  • 格式: groupByKey()
  • 说明: 根据key进行分组操作
rdd = sc.parallelize([('c01','张三'),('c02','李四'),('c02','王五'),('c03','赵六'),('c02','田七'),('c02','周八'),('c03','李九')])# 需求: 根据班级分组统计
rdd_collect = rdd.groupByKey().mapValues(list).collect()
print(rdd_collect)结果:[('c01', ['张三']), ('c02', ['李四', '王五', '田七', '周八']), ('c03', ['赵六', '李九'])]

reduceByKey()
  • 格式:  reduceByKey(fn)
  • 说明: 根据key进行分组, 将一个组内的value数据放置到一个列表中, 对这个列表基于 传入函数进行聚合计算操作
rdd = sc.parallelize([('c01','张三'),('c02','李四'),('c02','王五'),('c03','赵六'),('c02','田七'),('c02','周八'),('c03','李九')])# 需求: 统计每个班级有多少个人
rdd_collect = rdd.map(lambda kv: (kv[0],1)).reduceByKey(lambda agg, curr: agg + curr).collect()
print(rdd_collect)结果:[('c01', 1), ('c02', 4), ('c03', 2)]# 如果不转为1:
rdd.reduceByKey(lambda agg,curr: agg + curr).collect()    
结果: [('c01', '张三'), ('c02', '李四王五田七周八'), ('c03', '赵六李九')]

sortByKey()算子
  • 格式: sortByKey(ascending = True|False)
  • 说明: 根据key进行排序操作, 默认按照key进行升序排序, 如果需要倒序, 设置 ascending  为False
rdd = sc.parallelize([('c03','张三'),('c05','李四'),('c011','王五'),('c09','赵六'),('c02','田七'),('c07','周八'),('c06','李九')])# 根据班级序号排序
rdd.sortByKey().collect()结果: 字典序 如果key是字符串[('c011', '王五'), ('c02', '田七'), ('c03', '张三'), ('c05', '李四'), ('c06', '李九'), ('c07', '周八'), ('c09', '赵六')]

动作算子

collect() 算子

  • 格式: collect()
  • 作用: 收集各个分区的数据, 将数据汇总到一个大的列表返回

reduce() 算子

  • 格式: reduce(fn)
  • 作用: 根据传入的函数对数据进行聚合操作
rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10])# 求第1数累加到最后一个数的和
rdd.reduce(lambda agg,curr: agg + curr)结果:55

first()算子

  • 格式: first()
  • 说明: 获取第一个元素
rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10])# 获取数据集中的第一个元素
rdd.first()结果:1

take() 算子

  • 格式: take(N)
  • 说明: 获取前N个元素, 类似于limit操作
rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10])# 获取数据集中的前5个元素
rdd.take(5)结果
[1, 2, 3, 4, 5]

top() 算子

  • 格式: top(N, [fn])
  • 说明: 对数据集进行倒序排序操作, 如果是kv类型, 默认是针对key进行排序, 获取前N个元素
  • fn: 可以自定义排序, 根据谁来排序
rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10])rdd.top(3)
结果:
[10, 9, 8]rdd = sc.parallelize([('c03','张三'),('c05','李四'),('c011','王五'),('c09','赵六'),('c02','田七'),('c07','周八'),('c06','李九')])rdd.top(3)
结果:
[('c09', '赵六'), ('c07', '周八'), ('c06', '李九')]rdd = sc.parallelize([('c03',5),('c05',9),('c011',2),('c09',6),('c02',80),('c07',12),('c06',10)])rdd.top(3,lambda kv: kv[1])
结果:
[('c02', 80), ('c07', 12), ('c06', 10)]

count()算子

  • 格式: count()
  • 说明: 统计多少个
rdd = sc.parallelize([('c03',5),('c05',9),('c011',2),('c09',6),('c02',80),('c07',12),('c06',10)])rdd.count()
结果:7

foreach()算子

  • 格式: foreach(fn)
  • 说明: 对数据集进行遍历操作, 遍历后做什么, 取决于传入的函数
rdd = sc.parallelize([('c03',5),('c05',9),('c011',2),('c09',6),('c02',80),('c07',12),('c06',10)])rdd.foreach(lambda kv: print(kv))
结果:('c03', 5)('c05', 9)('c011', 2)('c09', 6)('c02', 80)('c07', 12)('c06', 10)

takeSample()算子

  • 格式: takeSample(True|False, N,seed(种子值))
    • 参数1: 是否允许重复采样
    • 参数2: 采样多少个, 如果允许重复采样, 采样个数不限制, 否则最多等于本身数量个数
    • 参数3: 设置种子值, 值可以随便写, 一旦写死了, 表示每次采样的内容也是固定的(可选的) 如果没有特殊需要, 一般不设置
  • 作用: 数据抽样
rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10])rdd.takeSample(True,5)
[9, 9, 4, 8, 9]
rdd.takeSample(True,5)
[3, 8, 1, 3, 9]
rdd.takeSample(False,5)
[6, 1, 8, 7, 3]
rdd.takeSample(False,5)
[5, 7, 6, 3, 8]
rdd.takeSample(False,20)
[2, 10, 7, 5, 8, 9, 3, 4, 6, 1]
rdd.takeSample(False,5) 
[8, 3, 10, 7, 9]rdd.takeSample(False,5,2)  
[6, 10, 4, 5, 7]
rdd.takeSample(False,5,2)
[6, 10, 4, 5, 7]
rdd.takeSample(False,5,2)
[6, 10, 4, 5, 7]
rdd.takeSample(False,3,2)
[6, 10, 4]

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...