楼主目前在百度实习,刚学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)]