1 简要介绍
算子:分布式集合对象上的API。
RDD算子分为,
- 转换算子Transformation:返回值仍旧是RDD。它是懒加载的,如果没有action算子,它是不工作的。
- action算子:返回值不是RDD。
对于这两类算子来说,转换算子,相当于在构建执行计划;action算子是执行计划的开关。
2 转换算子
2.1 map
map算子:将RDD中的数据一条条处理。
rdd.map(func)
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3 ,4, 5], 3)
print(rdd.map(lambda data: data * 10).collect())
输出,
[10, 20, 30, 40, 50]
2.2 flatMap
功能:对rdd先执行map操作,然后进行解除嵌套操作。
解除嵌套,
#嵌套的list
lst = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
#如果解除了嵌套
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 3)
print(rdd.flatMap(lambda x: x).collect())
输出为,
[1, 2, 3, 4, 5, 6, 7, 8, 9]
2.3 reduceByKey
功能:针对KV型RDD,自动按照key分组,然后根据你提供的聚合逻辑,完成组内数据的聚合。
rdd.reduceByKey(func)
#func: (v, v) -> v
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2)], 3)
print(rdd.reduceByKey(lambda x, y: x + y).collect())
输出为,
[('b', 3), ('a', 6)]
2.4 mapValues
功能:针对二元元组RDD,对其内部的二元元组的Value执行map操作。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2)], 3)
print(rdd.mapValues(lambda x: x * 10).collect())
输出为,
[('a', 10), ('a', 20), ('a', 30), ('b', 10), ('b', 20)]
2.5 groupBy
功能:将RDD的数据进行分组。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2)], 3)
print(rdd.groupBy(lambda x: x[0]).collect())
print(rdd.groupBy(lambda x: x[0]).map(lambda x: (x[0], list(x[1]))).collect())
结果为,
[('b', <pyspark.resultiterable.ResultIterable object at 0x7a945583b5f0>), ('a', <pyspark.resultiterable.ResultIterable object at 0x7a945c11faa0>)]
[('b', [('b', 1), ('b', 2)]), ('a', [('a', 1), ('a', 2), ('a', 3)])]
2.6 filter
功能:过滤想要的数据进行保留。
保留func返回值为true的数据。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2)], 3)
print(rdd.filter(lambda x: x[1] >= 2).collect())
结果为,
[('a', 2), ('a', 3), ('b', 2)]
2.7 distinct
功能:对RDD数据进行去重,返回新的RDD。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([('a', 1), ('a', 1), ('a', 2), ('b', 1), ('b', 1)], 3)
print(rdd.distinct().collect())
结果为,
[('a', 1), ('a', 2), ('b', 1)]
2.8 union
功能:2个rdd合并成1个rdd返回。
rdd1.union(rdd2)
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd1 = sc.parallelize([1, 2, 3, 4], 3)
rdd2 = sc.parallelize(['1', '2', '3'], 3)
print(rdd1.union(rdd2).collect())
结果为,
[1, 2, 3, 4, '1', '2', '3']
2.9 join
功能:对两个RDD执行JOIN操作,可实现SQL的内连接或外连接,只能用于KV型RDD。关联条件按照二元元组的KEY来进行。
语法:
rdd.join(other_rdd) #内连接
rdd.leftOuterJoin(other_rdd) #左外连接
rdd.rightOuterJoin(other_rdd) #右外连接
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd1 = sc.parallelize([('001', 'zhangsan'), ('002', 'lisi'), ('003', 'wangwu')], 3)
rdd2 = sc.parallelize([('001', '销售部'), ('002', '硬件部'), ('000', '软件部')], 1)
print(rdd1.join(rdd2).collect())
print(rdd1.leftOuterJoin(rdd2).collect())
print(rdd1.rightOuterJoin(rdd2).collect())
结果为,
[('001', ('zhangsan', '销售部')), ('002', ('lisi', '硬件部'))]
[('003', ('wangwu', None)), ('001', ('zhangsan', '销售部')), ('002', ('lisi', '硬件部'))]
[('000', (None, '软件部')), ('001', ('zhangsan', '销售部')), ('002', ('lisi', '硬件部'))]
2.10 intersection
功能:求2个rdd的交集,返回一个新rdd。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd1 = sc.parallelize([1, 2, 3], 3)
rdd2 = sc.parallelize([2, 3, 4, 5], 1)
print(rdd1.intersection(rdd2).collect())
结果为,
[2, 3]
2.11 glom
功能:将RDD的数据加上嵌套,这个嵌套按照分区来进行。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 3)
print(rdd.glom().collect())
结果为,
[[1, 2], [3, 4], [5, 6, 7]]
2.12 groupByKey
功能:针对KV型RDD,自动按照key分组。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([('a', 1), ('a', 2), ('b', 3), ('b', 4)], 3)
print(rdd.groupByKey().collect())
print(rdd.groupByKey().map(lambda x: (x[0], list(x[1]))).collect())
结果为,
[('b', <pyspark.resultiterable.ResultIterable object at 0x6ffdb97bb5f0>), ('a', <pyspark.resultiterable.ResultIterable object at 0x6ffdb8c8b7a0>)]
[('b', [3, 4]), ('a', [1, 2])]
2.13 sortBy
功能:对RDD数据进行排序,基于你指定的排序依据。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 3)
print(rdd.sortBy(lambda x: x, ascending=False, numPartitions=2).collect())
结果为,
[7, 6, 5, 4, 3, 2, 1]
2.14 sortByKey
功能:针对KV型RDD,按照key进行排序。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([('a', 1), ('b', 2), ('A', 3), ('B', 4)], 3)
print(rdd.sortByKey(ascending=True, numPartitions=2, keyfunc=lambda key: str(key).lower()).collect())
输出为,
[('a', 1), ('A', 3), ('b', 2), ('B', 4)]
2.15 mapPartitions
一次传递的是一整个分区的数据。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 2)
print(rdd.mapPartitions(lambda lst: [x * 10 for x in lst]).collect())
结果为,
[10, 20, 30, 40, 50, 60, 70]
2.16 partitionBy
功能:对KV型RDD进行自定义分区操作。
用法:
rdd.partitionBy(参数1,参数2)
- 参数1:重新分区后有几个分区
- 参数2:定义分区规则,函数传入
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([(1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0)], 2)
print(rdd.glom().collect())
print(rdd.partitionBy(2, lambda x: (x % 2)).glom().collect())
结果为,
[[(1, 0), (2, 0), (3, 0)], [(4, 0), (5, 0), (6, 0), (7, 0)]]
[[(2, 0), (4, 0), (6, 0)], [(1, 0), (3, 0), (5, 0), (7, 0)]]
2.17 repartition
功能:对RDD的分区执行重新分区,仅数量。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([(1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0)], 3)
print(rdd.glom().collect())
print(rdd.repartition(2).glom().collect())
结果为,
[[(1, 0), (2, 0)], [(3, 0), (4, 0)], [(5, 0), (6, 0), (7, 0)]]
[[(5, 0), (6, 0), (7, 0)], [(1, 0), (2, 0), (3, 0), (4, 0)]]
3 action算子
3.1 countByKey
功能:统计key出现的次数,一般适用于KV型RDD。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([('a', 1), ('a', 2), ('b', 3), ('c', 4)], 3)
print(rdd.countByKey())
结果为,
defaultdict(<class 'int'>, {'a': 2, 'b': 1, 'c': 1})
3.2 collect
功能:将RDD各个分区内的数据,统一收集到Driver中,形成一个List对象。
要注意,如果结果数据集很大,会把Driver内存撑爆。
3.3 reduce
功能:将RDD数据集按照你传入的逻辑进行聚合。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5], 3)
print(rdd.reduce(lambda a, b: a + b))
结果为,
15
3.4 fold
功能:和reduce一样,接受传入逻辑进行聚合,聚合是带有初始值的。
这个初始值,会作用在:
- 分区内聚合
- 分区间聚合
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 1, 1], 1)
print(rdd.glom().collect())
print(rdd.fold(10, lambda a, b: a + b))
结果为,
[[1, 1, 1]]
23
3.5 first
功能:取出RDD的第一个元素。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3], 3)
print(rdd.first())
结果为,
1
3.6 take
功能:取RDD的前N个元素,组合成List返回。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 3)
print(rdd.take(4))
结果为,
[1, 2, 3, 4]
3.7 top
功能:对RDD数据集进行降序排列,取前N个。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 3)
print(rdd.top(4))
结果为,
[7, 6, 5, 4]
3.8 count
功能:计算RDD有多少条数据,返回值是一个数字。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 3)
print(rdd.count())
结果为,
7
3.9 takeSample
功能:随机抽样RDD的数据。
用法:
takeSample(参数1: True or False, 参数2: 采样数, 参数3: 随机数种子)
- 参数1: True表示运行取同一个数据;False表示不允许取同一个数据。
- 参数2: 抽样要几个。
- 参数3: 随机数种子。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 3)
print(rdd.takeSample(False, 5))
结果为,
[4, 6, 3, 5, 2]
3.10 takeOrdered
功能:对RDD进行排序取前N个。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 3)
print(rdd.takeOrdered(3, lambda x: x))
print(rdd.takeOrdered(3, lambda x: -x))
结果为,
[1, 2, 3]
[7, 6, 5]
3.11 foreach
功能:对RDD的每一个元素,执行你提供的逻辑操作。这个方法没有返回值。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 3)
print(rdd.foreach(lambda x: print(x * 10)))
结果为,
50tage 0:> (0 + 3) / 3]
60
70
30
40
10
20
None
3.12 saveAsTextFile
功能:将RDD的数据写入文本文件中。支持本地写出、hdfs等文件系统。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 1)
rdd.saveAsTextFile("out")
结果为,

3.13 foreachPartition
功能:和普通foreach一致,一次处理的是一整个分区的数据。
使用示例,
from pyspark import SparkConf, SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
sc = SparkContext(conf=conf)
rdd = sc.parallelize([1, 2, 3, 4, 5, 6, 7], 2)
def f(iter):
res = []
for x in iter:
res.append(x * 10)
print(res)
print(rdd.foreachPartition(f))
结果为,
[40, 50, 60, 70] (0 + 2) / 2]
[10, 20, 30]
None
6134

被折叠的 条评论
为什么被折叠?



