Spark算子(二)之Pair RDD操作
文章目录
- Spark算子(二)之Pair RDD操作
- 3、Pair RDD的转化操作
- 1)`reduceByKey(func)`:
- 2)`groupBy(func)`:
- 3)`groupByKey()`:
- 4)`combineByKey(a1,a2,a3,a4,a5)`:
- 5)`mapValues(func)`:
- 6)`flatMapValues(func)`:
- 7)`keys()`:
- 8)`values()`:
- 9)`sortBy(func,ascending)`:
- 10)`sortByKey(ascending)`:
- 11)`zip(otherDataset)`:
- 12)`subtractByKey(otherDataset)`:
- 13)`cogroup(otherDataset,numPartitions)`:
- 14)`join(otherDataset,numPartitions)`:
- 15)`leftOuterJoin(otherDataset,numPartitions)`:
- 16)`rightOuterJoin(otherDataset,numPartitions)`:
- 4、Pair RRD的行动操作
3、Pair RDD的转化操作
1)reduceByKey(func)
:
对元素为K-V对的RDD中Key相同的元素的Value进行reduce操作。
对rdd1中Key相同的元素的值求和。
>>> rdd1 = sc.parallelize([(1,2),(3,4),(3,6)])
>>> rdd2 = rdd1.reduceByKey(lambda x,y:x+y)
>>> print(rdd2.collect())
[(1,2),(3,10)]
2)groupBy(func)
:
func返回Key,传入的RDD的各个元素根据这个Key进行分组。
对rdd1中 的元素按奇偶进行分组。
>>> rdd1 = sc.parallelize(range(1,10))
>>> rdd2 = rdd1.groupBy(lambda x:x%2)
>>> print(rdd2.map(lambda x:(x[0],list(x[1]))).collect())
[(0, [2, 4, 6, 8]), (1, [1, 3, 5, 7, 9])]
3)groupByKey()
:
对元素为K-V对的RDD中Key相同的元素进行分组。
对rdd1中相同的Key进行分组。
>>> rdd1 = sc.parallelize([('a',1),('b',2),('a',3),('c',4),('b',0)])
>>> rdd2 = rdd1.groupByKey()
>>> print(rdd2.map(lambda x:(x[0],list(x[1]))).collect())
[('a', [1, 3]), ('c', [4]), ('b', [2, 0])]
4)combineByKey(a1,a2,a3,a4,a5)
:
a1:createCombiner 创建组合器函数
a2:mergeValue 合并值函数
a3:mergeCombiners 合并组合器函数
a4:partitioner 已有或自定义的分区函数
a5:mapSideCombine 表示是否在map端进行Combine操作
①在第一次遇到Key时创建组合器函数(createCombiner),将RDD数据集中的V类型值转换成C类型值(V => C);
②再次遇到相同的Key时,合并值函数(mergeValue)将C类型值与这次传入的V类型值合并成一个C类型值(C,V) => C;
③合并组合器函数(mergeCombiners)将C类型值两两合并成一个C类型值;
④partitioner表示使用已有的或自定义的分区函数,默认为HashPartitioner;
⑤mapSideCombine表示是否在map端进行Combine操作,默认为True。
统计物品数。
>>> data = [("coffee",1),("coffee",2),("panda",3),("coffee",9)]
>>> rdd1 = sc.parallelize(data,2)
>>> createComb = (lambda v: (v,1))
>>> mergeVal = (lambda acc,v: (acc[0] + v,acc[1] + 1))
>>> mergeComb = (lambda acc1,acc2: (acc1[0] + acc2[0],acc1[1] + acc2[1]))
>>> rdd2 = rdd1.combineByKey(createComb,mergeVal,mergeComb)
>>> print(rdd2.collect())
[('coffee', (12, 3)), ('panda', (3, 1))]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iuA9Yn87-1599741820081)(C:\Users\90676\Desktop\博客\大数据学习·Spark算子\2671133-bc10832f9042af13.webp)]
5)mapValues(func)
:
原RDD中的Key保持不变,与新的Value一起组成新的RDD中的元素。因此,该函数适用于元素为K-V对的RDD。
对rdd1中的Value加3。
>>> rdd1 = sc.parallelize([("a",3),("b",4),("c",5)])
>>> rdd2 = rdd1.mapValues(lambda x:x + 3)
>>> print(rdd2.collect())
[('a', 6), ('b', 7), ('c', 8)]
6)flatMapValues(func)
:
类似于mapValues,不同在于flatMapValues应用于元素为K-V对的RDD中的V值。每个元素的Value被输入函数映射为一系列的值,然后这些值再与原RDD中的Key组成一系列新的K-V对。
对rdd1中的Value取平方
>>> rdd1 = sc.parallelize([('A',(1,2,3)),('B',(4,5,6))])
>>> rdd2 = rdd1.flatMapValues(lambda x:[i * i for i in x])
>>> print(rdd2.collect())
[('A', 1), ('A', 4), ('A', 9), ('B', 16), ('B', 25), ('B', 36)]
7)keys()
:
返回RDD中的Key。
>>> rdd1 = sc.parallelize([('A',(1,2,3)),('B',(4,5,6))])
>>> rdd2 = rdd1.keys()
>>> print(rdd2.collect())
['A', 'B']
8)values()
:
返回RDD中的Value。
>>> rdd1 = sc.parallelize([('A',(1,2,3)),('B',(4,5,6))])
>>> rdd2 = rdd1.values()
>>> print(rdd2.collect())
[(1, 2, 3), (4, 5, 6)]
9)sortBy(func,ascending)
:
根据给定的func函数对RDD中的元素进行排序;
ascending默认是True,也就是升序。
>>> rdd1 = sc.parallelize([3,1,50,3,6,18])
>>> rdd2 = rdd1.sortBy(lambda x:x,False)
>>> print(rdd2.collect())
[50, 18, 6, 3, 3, 1]
10)sortByKey(ascending)
:
将元素按照Key排序;
ascending = True为升序,= False为降序。
>>> rdd1 = sc.parallelize([("B",66),("A",65),("D",68)])
>>> rdd2 = rdd1.sortByKey(True)
>>> print(rdd2.collect())
[('A', 65), ('B', 66), ('D', 68)]
11)zip(otherDataset)
:
将两个RDD的元素聚合在一起。
将rdd1和rdd2聚合在一起。
>>> rdd1 = sc.parallelize(['a','b','c'])
>>> rdd2 = sc.parallelize(['1','2','3'])
>>> rdd3 = rdd1.zip(rdd2)
>>> print(rdd3.collect())
[('a', '1'), ('b', '2'), ('c', '3')]
12)subtractByKey(otherDataset)
:
删除RDD中key与另一个RDD中Key相同的元素。
删除rdd1中Key与rdd2相同的元素。
>>> rdd1 = sc.parallelize([(1,2),(3,4),(3,6),(4,5)])
>>> rdd2 = sc.parallelize([(3,8),[4,9]])
>>> rdd3 = rdd1.subtractByKey(rdd2)
>>> print(rdd3.collect())
[(1, 2)]
13)cogroup(otherDataset,numPartitions)
:
对两个RDD,如(K,V)和(K,W),Key相同的元素分别做聚合,然后返回(K,Iterator<V>,Iterator<W>)形式的RDD,numPartitions设置分区数,提高作业并行度。
将rdd1与rdd2分组聚合。
>>> rdd1 = sc.parallelize([(1,2),(3,4),(3,6)])
>>> rdd2 = sc.parallelize([(3,8),(4,9)])
>>> rdd3 = rdd1.cogroup(rdd2)
>>> def prn(x):
... print('['),;print(x[0]),;print(','),
... for i in x[1]:print(list(i)),
... print(']')
...
>>> rdd3.foreach(prn)
[ 4 , [] [9] ]
[ 1 , [2] [] ]
[ 3 , [4, 6] [8] ]
14)join(otherDataset,numPartitions)
:
对两个RDD先进性cogroup操作形成新的RDD,再对每个Key下的元素进行笛卡尔积,运算numPartitions设置分区数,提高作业并行度。
将rdd1与rdd2内连接。
>>> rdd1 = sc.parallelize([(1,2),(3,4),(3,6)])
>>> rdd2 = sc.parallelize([(3,8),(4,9)])
>>> rdd3 = rdd1.join(rdd2)
>>> print(rdd3.collect())
[(3, (4, 8)), (3, (6, 8))]
15)leftOuterJoin(otherDataset,numPartitions)
:
左外连接,包括左RDD的所有数据,如果右边没有与之匹配的用None表示,numPartitions设置分区数,提高作业并行度。
将rdd1与rdd2左连接。
>>> rdd1 = sc.parallelize([(1,2),(3,4),(3,6)])
>>> rdd2 = sc.parallelize([(3,8),(4,9)])
>>> rdd3 = rdd1.leftOuterJoin(rdd2)
>>> print(rdd3.collect())
[(1, (2, None)), (3, (4, 8)), (3, (6, 8))]
16)rightOuterJoin(otherDataset,numPartitions)
:
右外连接,包括右RDD的所有数据,如果左边没有与之匹配的用None表示,numPartitions设置分区数,提高作业并行度。
将rdd1与rdd2右连接。
>>> rdd1 = sc.parallelize([(1,2),(3,4),(3,6)])
>>> rdd2 = sc.parallelize([(3,8),(4,9)])
>>> rdd3 = rdd1.rightOuterJoin(rdd2)
>>> print(rdd3.collect())
[(4, (None, 9)), (3, (4, 8)), (3, (6, 8))]
4、Pair RRD的行动操作
1)countByKey()
:
统计每个Key对应的Value个数。
统计rdd1中每个Key对应的Value个数。
>>> rdd1 = sc.parallelize([('b',1),('b',2),('a',3),('a',4),('a',5)])
>>> rdd2 = rdd1.countByKey()
>>> print(rdd2)
defaultdict(<type 'int'>, {'a': 3, 'b': 2})
2)collectAsMap()
:
作用于K-V类型的RDD上,与collect()不同的是,collectAsMap函数不包括重复的Key。对于重复的Key,后面的元素覆盖前面的元素。
删除rdd1中重复的Key值,只保留一个。
>>> rdd1 = sc.parallelize([('b',1),('b',2),('a',3),('a',4),('a',5)])
>>> rdd2 = rdd1.collectAsMap()
>>> print(rdd2)
{'a': 5, 'b': 2}
#>>> rdd3 = rdd1.collect()
#>>> print(rdd3)
#[('b', 1), ('b', 2), ('a', 3), ('a', 4), ('a', 5)]
3)lookup(Key)
:
作用于K-V类型的RDD上,返回指定Key所有的Value。
查找rdd1中Key对应的Value。
>>> rdd1 = sc.parallelize([('b',1),('b',2),('a',3),('a',4),('a',5)])
>>> rdd2 = rdd1.lookup('b')
>>> print(rdd2)
[1, 2]