大数据spark常用算子用法总结(个人学习笔记)

楼主目前在百度实习,刚学spark时困难重重,幸亏在百度实习的导师的帮助,年前学会了spark,并跑了几个程序,现在将学习过程中整理的spark算子代码用法给整理出来。

#coding=utf-8
#!/usr/bin/python

# from pyspark.sql import SQLContext, Row         #导入pyspark模块          
from pyspark import SparkContext, SparkConf
from pyspark.sql import SparkSession            #SparkSession 是 Spark SQL 的入口

“”"
该代码用于练习spark的各种算子操作,了解各种算子的具体用法
“”"

1.map算子

#map算子
def test_map():
    # map() 接收一个函数,把这个函数用于 RDD 中的每个元素,将函数的返回结果作为新的RDD
    spark = SparkSession.builder.appName("map").getOrCreate()  
    sc = spark.sparkContext  

    #map
    x= sc.parallelize([1,2,3])      #parallelize函数将列表转化为一个RDD对象
    y =x.map(lambda x:(x,x**2))
    print(x.collect())              
    print(y.collect())              
    #[1,2,3]
    #[(1,1),(2,4),(3,9)]

2.filter算子

def test_filter():
    #filter 挑选符合条件的结果
    spark =SparkSession.builder.appName("filter").getOrCreate()
    sc = spark.sparkContext
    
    # filter
    x = sc.parallelize([1,2,3])
    y = x.filter(lambda x: x %2 == 1)
    print(x.collect())          
    print(y.collect())

    #[1,2,3]
    #[1,3]

3.flatMap算子

def test_flatMap():
    # 与map类似,将原RDD中的每个元素通过函数f转换为新的元素,并将这些元素放入一个集合,构成新的RDD
    spark =SparkSession.builder.appName("flatMap").getOrCreate()
    sc = spark.sparkContext

    #flatMap
    x = sc.parallelize([[1,2,3],[4,5,6]])
    y = x.flatMap(lambda x :x)
    print(x.collect())
    print(y.collect())

    #[[1,2,3],[4,5,6]]
    #[1,2,3,4,5,6]

4.reduceByKey算子

def test_reduceByKey():
    """ 
    reduceByKey将相同key的前两个value传给输入函数,产生一个新的return值,
    新产生的return值与下一个value(第三个元素)组成两个元素,再被传给输入函数,直到最后只有一个值为止。
    """
    spark =SparkSession.builder.appName("reduceByKey").getOrCreate()
    sc = spark.sparkContext

    x = sc.parallelize([('B',1),('B',2),('A',3),('A',4),('A',5)])
    y = x.reduceByKey(lambda x,y:x+y)
    print(x.collect())
    print(y.collect())

    # [('B',1),('B',2),('A',3),('A',4),('A',5)]
    # [('A', 12), ('B', 3)]

5.groupByKey算子

def test_groupByKey():
    # groupByKey 按照key进行分组,直接进行shuffle
    spark =SparkSession.builder.appName("groupByKey").getOrCreate()
    sc = spark.sparkContext

    x = sc.parallelize([('B',1),('B',2),('A',3),('A',4),('A',5)])
    y = x.groupByKey()
    print(x.collect())
    print([(j[0],[i for i in j[1]]) for j in y.collect()])
    
    #[('B',1),('B',2),('A',3),('A',4),('A',5)]
    #[('A', [3, 4, 5]), ('B', [1, 2])]

6.aggregateByKey算子

def test_aggregateByKey():
    """
    aggregateByKey, 先说分为三个参数的:
    第一个参数是, 每个key的初始值
    第二个是个函数, Seq Function, 经测试这个函数就是用来先对每个分区内的数据按照key分别进行定义进行函数定义的操作
    第三个是个函数, Combiner Function, 对经过 Seq Function 处理过的数据按照key分别进行进行函数定义的操作
    """
    # 按分区聚合,再总的聚合,每次要跟初始值交流
    spark =SparkSession.builder.appName("aggregateByKey").getOrCreate()
    sc = spark.sparkContext

    x = sc.parallelize([('B',1),('B',2),('A',3),('A',4),('A',5)])
    zeroValue = []
    mergeVal = (lambda aggregated,el:aggregated + [(el,el**2)])
    mergeComb = (lambda agg1,agg2: agg1+agg2)
    y = x.aggregateByKey(zeroValue,mergeVal,mergeComb)
    print(x.collect())
    print(y.collect())

    # [('B',1),('B',2),('A',3),('A',4),('A',5)]
    # [('A', [(3, 9), (4, 16), (5, 25)]), ('B', [(1, 1), (2, 4)])]

7.union算子

def test_union():
    # 将两个RDD合并,不去重
    spark =SparkSession.builder.appName("union").getOrCreate()
    sc = spark.sparkContext

    #union
    x = sc.parallelize(['A','A','B'])
    y = sc.parallelize(['D','C','A'])
    z = x.union(y)
    print(x.collect())
    print(y.collect())
    print(z.collect())

    # ['A','A','B'] ['D','C','A']
    # ['A', 'A', 'B', 'D', 'C', 'A']

8.take算子

def test_take():
    # take函数用于获取RDD中从0到num-1下标的元素(不排序)
    spark =SparkSession.builder.appName("take").getOrCreate()
    sc = spark.sparkContext

    #take
    x = sc.parallelize([1,3,1,2,3])
    y = x.take(num=3)
    print(x.collect())
    print(y)
    
    #[1, 3, 1, 2, 3]
    #[1, 3, 1]

9.first算子

def test_first():
    # first返回RDD中的第一个元素,不排序
    spark =SparkSession.builder.appName("first").getOrCreate()
    sc = spark.sparkContext

    #first
    x = sc.parallelize([1,3,1,2,3])
    y = x.first()
    print(x.collect())
    print(y)

    # [1, 3, 1, 2, 3]
    # 1

10.foreach算子

def test_foreach():
    # foreach:用于遍历RDD,将函数f应用于每一个元素,无返回值(action算子)。
    spark =SparkSession.builder.appName("foreach").getOrCreate()
    sc = spark.sparkContext

    #foreach
    def f(x) :
        print(x)
    x = sc.parallelize([1,2,3,4,5])
    y = x.foreach(f)        #先输出y值,因为y调用了f函数,里面包含了print
    print(x.collect())      #这一步才会执行打印x
    print(y)            

    # 1
    # 2
    # 3
    # 4
    # 5
    # [1, 2, 3, 4, 5]
    # None

11.count算子

def test_count():
    # count用于统计RDD中元素个数
    spark =SparkSession.builder.appName("count").getOrCreate()
    sc = spark.sparkContext

    #count
    x = sc.parallelize([1,3,2])
    y = x.count()
    print(x.collect())
    print(y)

    # [1, 3, 2]
    # 3

12.collect算子

def test_collect():
    """
    如果数据量比较大的时候,尽量不要使用collect函数,因为这可能导致Driver端内存溢出问题。
    建议使用rdd.take(100).foreach(println),
    而不使用rdd.collect().foreach(println)
    """
    spark =SparkSession.builder.appName("collect").getOrCreate()
    sc = spark.sparkContext

    #collect
    x = sc.parallelize([1,2,3])
    y = x.collect()
    print(x)
    print(y)
    
    # ParallelCollectionRDD[0] at parallelize at PythonRDD.scala:184
    # [1, 2, 3]

13.sample算子

def test_sample():
    """
    1、withReplacement:元素是否可以重复抽样
    2、fraction:期望样本的大小作为RDD大小的一部分, 
    当withReplacement=false时:选择每个元素的概率;fraction一定是[0,1]区间内的数字 ; 
    当withReplacement=true时:选择每个元素的期望次数; fraction必须大于等于0。
    3、seed:随机数生成器的种子,不好把控,建议默认。

    """

    spark =SparkSession.builder.appName("sample").getOrCreate()
    sc = spark.sparkContext

    #sample
    x = sc.parallelize(range(7))
    ylist = [x.sample(withReplacement =False,fraction =0.5) for i in range(5)]
    print('x =' + str(x.collect()))
    for cnt,y in zip(range(len(ylist)),ylist):
        print('sample:' + str(cnt) + 'y =' + str(y.collect()))

    # x =[0, 1, 2, 3, 4, 5, 6]
    # sample:0y =[0, 1, 5, 6]
    # sample:1y =[1, 3, 5, 6]
    # sample:2y =[3]
    # sample:3y =[2, 4, 6]
    # sample:4y =[1, 4, 6]

14.takeSample算子

def test_takeSample():
    """
    返回一个数组 
    该方法仅在预期结果数组很小的情况下使用,因为所有数据都被加载到driver的内存中。
    1、withReplacement:元素可以多次抽样(在抽样时替换)
    2、num:返回的样本的大小
    3、seed:随机数生成器的种子,不好把控,建议默认
    """
    spark =SparkSession.builder.appName("takeSample").getOrCreate()
    sc = spark.sparkContext
    
    # tekeSample
    x = sc.parallelize(range(7))
    ylist = [x.takeSample(withReplacement=False,num=3) for i in range(5)]
    print('x = ' + str(x.collect()))
    for cnt,y in zip(range(len(ylist)),ylist):
        print('sample'+str(cnt)+'y =' + str(y))

    # x = [0, 1, 2, 3, 4, 5, 6]
    # sample0y =[1, 3, 5]
    # sample1y =[6, 1, 2]
    # sample2y =[4, 5, 3]
    # sample3y =[3, 0, 5]
    # sample4y =[6, 2, 3]

15.sampleByKey算子

def test_sampleByKey():
    # 用法参考sample
    spark =SparkSession.builder.appName("sampleByKey").getOrCreate()
    sc = spark.sparkContext

    x = sc.parallelize([('A',1),('B',2),('C',3),('B',4),('A',5)])
    y = x.sampleByKey(withReplacement = False,fractions = {'A':0.5,'B':1,'C':0.2})
    print(x.collect())
    print(y.collect())
    # [('A', 1), ('B', 2), ('C', 3), ('B', 4), ('A', 5)]
    # [('B', 2), ('B', 4)]

16.repartition算子

def test_repartition():
    # repartition 和 partitionBy 都是对数据进行重新分区。区别在于partitionBy 只能用于 PairRdd。
    spark =SparkSession.builder.appName("repartition").getOrCreate()
    sc = spark.sparkContext

    #repartition
    x = sc.parallelize([1,2,3,4,5],2)
    y = x.repartition(numPartitions = 3)
    print(x.glom().collect())
    print(y.glom().collect())
    # [[1, 2], [3, 4, 5]]
    # [[], [1, 2], [3, 4, 5]]

17.partitionBy算子

def test_partitionBy():
    # 函数根据partitioner函数生成新的ShuffleRDD,将原RDD重新分区。仅使用(k, v)中的k用来分区。
    spark =SparkSession.builder.appName("partitionBy").getOrCreate()
    sc = spark.sparkContext

    #partitionBy
    x =sc.parallelize([(0,1),(1,2),(2,3)],2)
    y = x.partitionBy(numPartitions = 3,partitionFunc = lambda x:x)
    print(x.glom().collect())
    print(y.glom().collect())

    # [[(0, 1)], [(1, 2), (2, 3)]]
    # [[(0, 1)], [(1, 2)], [(2, 3)]]

18.intersection算子

def test_intersection():
    # intersection :返回两个RDD的交集,并且去重
    spark =SparkSession.builder.appName("intersection").getOrCreate()
    sc = spark.sparkContext

    x =sc.parallelize(['A','A','B'])
    y =sc.parallelize(['A','C','D'])
    z =x.intersection(y)
    print(x.collect())
    print(y.collect())
    print(z.collect())

    # ['A', 'B', 'C']
    # ['A', 'C', 'D']
    # ['A']

19.subtract算子

def test_subtract():
    # 返回在RDD中出现,并且不在otherRDD中出现的元素,不去重。
    spark =SparkSession.builder.appName("subtract").getOrCreate()
    sc = spark.sparkContext

    x = sc.parallelize([('C',4),('B',3),('A',2),('A',1)])
    y = sc.parallelize([('C',8),('A',2),('D',1)])
    z = x.subtract(y)
    print(x.collect())
    print(y.collect())
    print(z.collect())

    # [('C', 4), ('B', 3), ('A', 2), ('A', 1)]
    # [('C', 8), ('A', 2), ('D', 1)]
    # [('B', 3), ('C', 4), ('A', 1)]

20.subtractByKey算子

def test_subtractByKey():
    # rdd.subtractByKey(other),删除RDD中键与other RDD中键相同的元素。
    spark =SparkSession.builder.appName("subtractByKey").getOrCreate()
    sc = spark.sparkContext

    x = sc.parallelize([('C',4),('B',3),('A',2),('A',1)])
    y = sc.parallelize([('A',5),('D',6),('A',7),('D',8)])
    z = x.subtractByKey(y)
    print(x.collect())
    print(y.collect())
    print(z.collect())

    # [('C', 4), ('B', 3), ('A', 2), ('A', 1)]
    # [('A', 5), ('D', 6), ('A', 7), ('D', 8)]
    # [('C', 4), ('B', 3)]

21.join算子

def test_join():
    # join类似于SQL的inner join操作,返回结果是前面和后面集合中配对成功的,过滤掉关联不上的。
    spark =SparkSession.builder.appName("join").getOrCreate()
    sc = spark.sparkContext

    # join
    x =sc.parallelize([('C',4),('B',3),('A',2),('A',1)])
    y =sc.parallelize([('A',8),('B',7),('A',6),('D',5)])
    z =x.join(y)
    print(x.collect())
    print(y.collect())
    print(z.collect())

    # [('C', 4), ('B', 3), ('A', 2), ('A', 1)]
    # [('A', 8), ('B', 7), ('A', 6), ('D', 5)]    
    # [('A', (2, 8)), ('A', (2, 6)), ('A', (1, 8)), ('A', (1, 6)), ('B', (3, 7))]

22.leftOuterJoin算子

def test_leftOuterJoin():
    # leftOuterJoin类似于SQL中的左外关联left outer join,返回结果以前面的RDD为主,关联不上的记录为空。只能用于两个RDD之间的关联,如果要多个RDD关联,多关联几次即可。
    spark =SparkSession.builder.appName("leftOuterJoin").getOrCreate()
    sc = spark.sparkContext

    x =sc.parallelize([('C', 4), ('B', 3), ('A', 2), ('A', 1)])
    y =sc.parallelize([('A', 8), ('B', 7), ('A', 6), ('D', 5)])
    z =x.leftOuterJoin(y)
    print(x.collect())
    print(y.collect())
    print(z.collect())

    # [('C', 4), ('B', 3), ('A', 2), ('A', 1)]
    # [('A', 8), ('B', 7), ('A', 6), ('D', 5)] 
    # [('A', (2, 8)), ('A', (2, 6)), ('A', (1, 8)), ('A', (1, 6)), ('C', (4, None)), ('B', (3, 7))]

23.rightOuterJoin算子


def test_rightOuterJoin():

    """
    rightOuterJoin类似于SQL中的左外关联right outer join,输出连接键匹配的记录,右侧的表无论匹配与否都输出。
    只能用于两个RDD之间的关联,如果要多个RDD关联,多关联几次即可。
    """
    spark =SparkSession.builder.appName("rightOuterJoin").getOrCreate()
    sc = spark.sparkContext

    x =sc.parallelize([('C', 4), ('B', 3), ('A', 2), ('A', 1)])
    y =sc.parallelize([('A', 8), ('B', 7), ('A', 6), ('D', 5)])
    z =x.rightOuterJoin(y)

    print(x.collect())
    print(y.collect())
    print(z.collect())

    # [('C', 4), ('B', 3), ('A', 2), ('A', 1)]
    # [('A', 8), ('B', 7), ('A', 6), ('D', 5)] 
    # [('A', (2, 8)), ('A', (2, 6)), ('A', (1, 8)), ('A', (1, 6)), ('B', (3, 7)), ('D', (None, 5))]

24.cartesian算子

def test_cartesian():
    # 此函数返回的是Pair类型的RDD,计算结果是当前RDD和other RDD中每个元素进行笛卡儿计算的结果。最后返回的是CartesianRDD。
    # 笛卡儿计算是很恐怖的,它会迅速消耗大量的内存,所以在使用这个函数的时候请小心。
    spark =SparkSession.builder.appName("cartesian").getOrCreate()
    sc = spark.sparkContext

    x =sc.parallelize(['A','B'])
    y =sc.parallelize(['C','D'])
    z =x.cartesian(y)
    print(x.collect())
    print(y.collect())
    print(z.collect())

    # ['A', 'B']
    # ['C', 'D']
    # [('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D')]

25.sortBy算子

def test_sortBy():
    # 排序操作
    spark =SparkSession.builder.appName("sortBy").getOrCreate()
    sc = spark.sparkContext

    x =sc.parallelize(['cat','apple','bat'])
    def keyGen(val):
        return val[0]
    y =x.sortBy(keyGen)
    print(y.collect())

    # ['apple', 'bat', 'cat']

26.sortByKey算子

def test_sortByKey():
    #按键的顺序进行排序
    spark =SparkSession.builder.appName("sortByKey").getOrCreate()
    sc = spark.sparkContext

    x =sc.parallelize([('B',1),('A',2),('C',3)])
    y =x.sortByKey()
    print(x.collect())
    print(y.collect())

    # [('B',1),('A',2),('C',3)]
    # [('A', 2), ('B', 1), ('C', 3)]

27.top算子

def test_top():
    # top函数用于从RDD中,按照默认(降序)或者指定的排序规则,返回前num个元素。
    spark =SparkSession.builder.appName("top").getOrCreate()
    sc = spark.sparkContext

    x =sc.parallelize([1,3,1,2,3])
    y =x.top(num=3)
    print(x.collect())
    print(y)

    # [1, 3, 1, 2, 3]
    # [3, 3, 2]

28.takeOrdered算子

def test_takeOrdered():
    # takeOrdered和top类似,只不过以和top相反的顺序返回元素。
    spark =SparkSession.builder.appName("takeOrdered").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([1,3,1,2,3])
    y =x.takeOrdered(num=3)
    print(x.collect())
    print(y)

    # [1, 3, 1, 2, 3]
    # [1, 1, 2]

29.max算子

def test_max():
    # max求最大值的算子,类似操作还有min,sum,mean,variance,stdev,sampleVariance,sampleStdev
    spark =SparkSession.builder.appName("max").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([1,3,2])
    y =x.max()
    print(x.collect())
    print(y)

    # [1, 3, 2]
    # 3

30.glom算子

def test_glom():
    # glom将每个分区中的元素放到一个数组
    spark =SparkSession.builder.appName("glom").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize(['C','B','A'],2)
    y =x.glom()
    print(x.collect())
    print(y.collect())

    # ['C','B','A']
    # [['C'], ['B', 'A']]

31.mapPartitions算子

def test_mapPartitions():
    # 该函数和map函数类似,只不过映射函数的参数由RDD中的每一个元素变成了RDD中每一个分区的迭代器。
    # 如果在映射的过程中需要频繁创建额外的对象,使用mapPartitions要比map高效的多。
    spark =SparkSession.builder.appName("mapPartitions").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([1,2,3],2)
    def f(iterator):
        yield sum(iterator)
    y = x.mapPartitions(f)
    print(x.glom().collect())
    print(y.glom().collect())

    # [[1], [2, 3]]
    # [[1], [5]]

32.distinct算子

def test_distinct():
    # 进行去重处理
    spark =SparkSession.builder.appName("distinct").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize(['A','A','B'])
    y =x.distinct()
    print(x.collect())
    print(y.collect())

    # ['A','A','B']
    # ['A', 'B']

33.groupBy算子

def test_groupBy():
    # groupBy(function) function返回key,传入的RDD的各个元素根据这个key进行分组。
    spark =SparkSession.builder.appName("groupBy").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([1,2,3])
    y =x.groupBy(lambda x : 'A' if (x%2==1) else 'B')
    print(x.collect())
    print([(j[0],[i for i in j[1]]) for j in y.collect()])

    # [1, 2, 3]
    # [('A', [1, 3]), ('B', [2])]

34.foreachPartition算子

def test_foreachPartition():
    # 对比foreach, 这个函数也是根据传入的function进行处理,但不同处在于,
    # 这里function的传入参数是一个partition里的迭代器。 foreachPartition打印也是随机的。
    spark =SparkSession.builder.appName("foreachPartition").getOrCreate() 
    sc = spark.sparkContext

    def f(x):
        print(list(x))
    x =sc.parallelize([1,2,3],5)
    y =x.foreachPartition(f)

    print(x.collect())
    print(x.glom().collect())
    print(y)

    # []
    # [1]
    # []
    # [2]
    # [3]
    # [1, 2, 3]
    # [[], [1], [], [2], [3]]
    # None

35.reduce算子

def test_reduce():
    # reduce将RDD中元素前两个传给输入函数,产生一个新的return值,
    # 新产生的return值与RDD中下一个元素(第三个元素)组成两个元素,再被传给输入函数,直到最后只有一个值为止。
    spark =SparkSession.builder.appName("reduce").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([1,2,3,4])
    y = x.reduce(lambda obj,accumulated :obj + accumulated)
    print(x.collect())
    print(y)

    # [1, 2, 3, 4]
    # 10

36.fold算子

def test_fold():
    # fold和reduce函数的区别在于它有初始值。
    spark =SparkSession.builder.appName("fold").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([1,2,3])
    neutral_zero_value =0
    y =x.fold(neutral_zero_value,lambda obj,accumulated:accumulated + obj)
    print(x.collect())
    print(y)

    # [1, 2, 3]
    # 6

37.aggregate算子

def test_aggregate():
    # 这个函数需要三个参数zeroValue, seqOp, combOp。zeroValue是初始值,seqOp和combOP是两个方法,
    # 其中seqOp方法是各分区内的聚集函数,是对每个分区操作; combOp是各分区间的组合函数,对每个分区的结果进行操作。
    spark =SparkSession.builder.appName("aggregate").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([2,3,4])
    neutral_zero_value =(0,1)
    seqOp =(lambda aggregated,el:(aggregated[0] +el,aggregated[1]*el))
    combOp =(lambda aggregated,el:(aggregated[0] +el[0],aggregated[1]*el[1]))
    y =x.aggregate(neutral_zero_value,seqOp,combOp)
    print(x.collect())
    print(y)

    # [2, 3, 4]
    # (9, 24)

38.countByValue算子

def test_countByValue():
    # 统计一个RDD中各个value的出现次数。返回一个map,map的key是元素的值,value是出现的次数。结果可以直接按dict使用
    spark =SparkSession.builder.appName("countByValue").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize(['a','a','a','b','c'])    #([1,3,1,2,3])
    y =x.countByValue()
    print(x.collect())
    print(y)
    print(y['a'])           #print(y[1])

    # ['a', 'a', 'a', 'b', 'c']
    # defaultdict(, {'a': 3, 'c': 1, 'b': 1})
    # 3

39.collectAsMap算子

def test_collectAsMap():
    # 功能和collect函数类似。该函数用于Pair RDD,最终返回Map类型的结果。如果RDD中同一个Key中存在多个Value,
    # 那么后面的Value将会把前面的Value覆盖,最终得到的结果就是Key唯一,而且对应一个Value。
    spark =SparkSession.builder.appName("collectAsMap").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([('c',1),('a',1),('b',2),('c',1)])
    y =x.collectAsMap()
    print(x.collect())
    print(y)

    # [('c', 1), ('a', 1), ('b', 2), ('c', 1)]
    # {'a': 1, 'c': 1, 'b': 2}

40.keys算子

def test_keys():
    # 输出各key-value型RDD中的key,形成新的RDD。不去重。
    spark =SparkSession.builder.appName("keys").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([('c',3),('a',1),('b',2),('b',3)])
    y =x.keys()
    print(x.collect())
    print(y.collect())

    # ['c', 'a', 'b', 'b']

41.values算子


def test_values():
    # 输出各key-value型RDD中的value,形成新的RDD。不去重。
    spark =SparkSession.builder.appName("values").getOrCreate() 
    sc = spark.sparkContext
    
    x =sc.parallelize([('c',3),('a',1),('b',1)])
    y =x.values()
    print(x.collect())
    print(y.collect())

    # [3, 1, 1]

42.redeceByKeyLocally算子

def test_reduceByKeyLocally():
    # 同reduceByKey,但是返回一个字典,而不是RDD。
    spark =SparkSession.builder.appName("reduceByKeyLocally").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([('B',1),('B',2),('A',3),('A',4),('A',5)])
    y =x.reduceByKeyLocally(lambda agg,obj:agg + obj)
    print(x.collect())
    print(y)

    # [('B', 1), ('B', 2), ('A', 3), ('A', 4), ('A', 5)]
    # {'A': 12, 'B': 3}

43.countByKey算子

def test_countByKey():
    # 统计每个key对应的value个数,需要注意的是rdd类型是pairRdd。
    spark =SparkSession.builder.appName("countByKey").getOrCreate() 
    sc = spark.sparkContext

    x = sc.parallelize([('B', 1), ('B', 2), ('A', 3), ('A', 4), ('A', 5)])
    y =x.countByKey()
    print(x.collect())
    print(y)

    # [('B', 1), ('B', 2), ('A', 3), ('A', 4), ('A', 5)]
    # defaultdict(, {'A': 3, 'B': 2})

44.combinByKey算子

def test_combinByKey():
    """
    1. createCombiner: V => C ,这个函数把value的第一个值作为参数,此时我们可以对其做些附加操作(类型转换)并把它返回 (这一步类似于初始化操作)
    2. mergeVal: (C, V) => C,该函数把元素V合并到之前的元素C(createCombiner)上 (这个操作在每个分区内进行)
    3. mergeComb: (C, C) => C,该函数把2个元素C合并 (这个操作在不同分区间进行)
    """
    spark =SparkSession.builder.appName("combineByKey").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([('B', 1), ('B', 2), ('A', 3), ('A', 4), ('A', 5)])
    createCombiner = (lambda el:[el,el**2])
    mergeVal =(lambda aggregated,el:aggregated+[(el,el**2)])
    mergeComb = (lambda agg1,agg2 : agg1 + agg2)
    y =x.combineByKey(createCombiner,mergeVal,mergeComb)
    print(x.collect())
    print(y.collect())

    # [('B', 1), ('B', 2), ('A', 3), ('A', 4), ('A', 5)]
    # [('A', [3, 9, (4, 16), (5, 25)]), ('B', [1, 1, (2, 4)])]

45.foldByKey算子

def test_foldByKey():
    # 按照键来对值进行乘法运算
    spark =SparkSession.builder.appName("foldByKey").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([('B', 1), ('B', 2), ('A', 3), ('A', 4), ('A', 5)])
    zeroValue =1
    y =x.foldByKey(zeroValue,lambda agg,x:agg*x)
    print(x.collect())
    print(y.collect())

    # [('B', 1), ('B', 2), ('A', 3), ('A', 4), ('A', 5)]
    # [('A', 60), ('B', 2)]

46.mapValue算子

def test_mapValues():
    # 对key-value形式的RDD中的value进行映射。
    spark =SparkSession.builder.appName("mapValues").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([('A',(1,2,3)),('B',(4,5))])
    y =x.mapValues(lambda x:[i**2 for i in x])
    print(x.collect())
    print(y.collect())

    # [('A',(1,2,3)),('B',(4,5))]
    # [('A', [1, 4, 9]), ('B', [16, 25])]

47.flatMapValues算子

def test_flatMapValues():
    # 对key-value形式的RDD中的value进行映射,将一个value展开成多个value。
    spark =SparkSession.builder.appName("flatMapValues").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize([('A',(1,2,3)),('B',(4,5))])
    y =x.flatMapValues(lambda x:[i**2 for i in x ])
    print(x.collect())
    print(y.collect())

    # [('A',(1,2,3)),('B',(4,5))]
    # [('A', 1), ('A', 4), ('A', 9), ('B', 16), ('B', 25)]

48.groupWith算子

def test_groupWith():
    # 将两个RDD中key相同的值组合在一起形成一个新的RDD。新RDD中,原相同key的各个value会变成新RDD相应key的集合型的value。
    spark =SparkSession.builder.appName("groupWith").getOrCreate() 
    sc = spark.sparkContext

    x=sc.parallelize([('C',4),('B',(3,3,)),('A',2),('A',(1,1))])
    y =sc.parallelize([('B',(7,7)),('A',6),('D',(5,5))])
    z=sc.parallelize([('D',9),('B',(8,8))])
    a =x.groupWith(y,z)

    for key,val in list(a.collect()):
        print(key,[list(i) for i in val])


    ('B', [[(3, 3)], [(7, 7)], [(8, 8)]])
    ('D', [[], [(5, 5)], [9]])
    ('A', [[2, (1, 1)], [6], []])
    ('C', [[4], [], []])

49.cogroup算子

def test_cogroup():
    # 功能和groupwith类似,将两个RDD中key相同的值组合在一起形成一个新的RDD 。
    spark =SparkSession.builder.appName("cogroup").getOrCreate() 
    sc = spark.sparkContext

    x=sc.parallelize([('C',4),('B',(3,3)),('A',2),('A',(1,1))])
    y=sc.parallelize([('A',8),('B',7),('A',6),('D',(5,5))])
    z =x.cogroup(y)
    for key,val in list(z.collect()):
        print(key,[list(i) for i in val])

    # ('A', [[2, (1, 1)], [8, 6]])
    # ('C', [[4], []])
    # ('B', [[(3, 3)], [7]])
    # ('D', [[], [(5, 5)]])

50keyBy算子


def test_keyBy():
    #为各个元素,按指定的函数生成key,形成key-value的RDD。
    spark =SparkSession.builder.appName("keyBy").getOrCreate() 
    sc = spark.sparkContext

    x = sc.parallelize([1,2,3])
    y = x.keyBy(lambda x :x**2)
    print(x.collect())
    print(y.collect())

    # [1,2,3]
    # [(1, 1), (4, 2), (9, 3)]
    

51.coalesce算子

def test_coalesce():
    # 分区算子
    spark =SparkSession.builder.appName("coalesce").getOrCreate() 
    sc = spark.sparkContext
    
    x=sc.parallelize([1,2,3,4,5],2)
    y=x.coalesce(numPartitions=1)
    print(x.glom().collect())
    print(y.glom().collect())

    # [[1, 2], [3, 4, 5]]
    # [[1, 2, 3, 4, 5]]

52.zip算子

def test_zip():
    # zip函数用于将两个RDD组合成Key/Value形式的RDD,这里默认两个RDD的partition数量以及元素数量都相同,否则会抛出异常。
    spark =SparkSession.builder.appName("zip").getOrCreate() 
    sc = spark.sparkContext

    x =sc.parallelize(['B','A','A'])
    y =x.map(lambda x:ord(x))
    z =x.zip(y)
    print(x.collect())
    print(y.collect())
    print(z.collect())

    # ['B', 'A', 'A']
    # [66, 65, 65]
    # [('B', 66), ('A', 65), ('A', 65)]

53.zipWithIndex算子

def test_zipWithIndex():
    # 该函数将RDD中的元素和这个元素在RDD中的ID(索引号)组合成键/值对。
    spark =SparkSession.builder.appName("zipWithIndex").getOrCreate() 
    sc = spark.sparkContext

    x=sc.parallelize(['B','A','A',],2)
    y=x.zipWithIndex()
    print(x.glom().collect())
    print(y.collect())

    # [['B'], ['A', 'A']]
    # [('B', 0), ('A', 1), ('A', 2)]

54.zipWithUniqueId算子

def test_zipWithUniqueId():

    """
    该函数将RDD中元素和一个唯一ID组合成键/值对,该唯一ID生成算法如下:
    每个分区中第一个元素的唯一ID值为:该分区索引号,
    每个分区中第N个元素的唯一ID值为:(前一个元素的唯一ID值) + (该RDD总的分区数)
    """
    spark =SparkSession.builder.appName("zipWithUniqueId").getOrCreate() 
    sc = spark.sparkContext

    x=sc.parallelize(['B','A','A'],2)
    y=x.zipWithUniqueId()
    print(x.glom().collect())
    print(y.collect())

    # [['B'], ['A', 'A']]
    # [('B', 0), ('A', 1), ('A', 3)]

你可能感兴趣的:(大数据spark常用算子用法总结(个人学习笔记))