spark中常用算子介绍

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   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YMWM_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值