大数据学习-Spark算子(二)之Pair RDD操作

Spark算子(二)之Pair RDD操作

Spark算子(一)之基本RDD操作

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]

大数据学习-Spark算子(三)之RDD的其他操作

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值