【spark】4.键值对操作

本文深入探讨了Spark中PairRDD的基本概念、创建方式、转化操作、聚合操作及并行度调优等关键内容,通过实例展示了如何利用PairRDD进行数据处理和分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


键值对RDD是Spark中许多操作所需要的常见数据类型,被称为pairRDD,提供了并行操作各个键或者跨界点重新进行数据分组的操作接口。

创建PairRDD

1.使用map()函数将普通RDD转换为PairRDD。

lines=sc.parallelize(["pandas","i like pandas"])
pairs = line.map(lambda x:(x[0],x))

PairRDD转化操作

以键值对{(1,2),(3,4),(3,6)}为例

函数名目的示例结果
reduceByKey(func)合并具有相同键的值rdd.reduceByKey(lambda x,y: x+y){(1,2),(3,10)}
groupByKey()按照键对RDD进行分组rdd.groupByKey(){(1,[2]),(3,[4,6])}
comBinByKey()使用不同的返回类型合并具有相同键的值示例见下
mapValues(func)对pair的每一个值应用一个函数而不改变键值rdd.mapValues(lambda x:x+1){(1,3),(3,5),(3,7)}
flatMapValues(func)对pair的每一个值应用一个迭代器行数,然后对返回的每一个元素都生成对用原值键值对记录rdd.flatMapValues(lambda x: (3,5)){(1,3),(1,5),(3,3),(3,5),(3,3),(3,5)}
keys()返回一个包含所有键的RDDrdd.keys(){1,3,3}
values()返回一个包含所有值的RDDrdd.values(){2,4,6}
sortByKey()返回一个根据键值排序的RDDrdd.sortByKey(){(1,2),(3,4),(3,6)}

以键值对{(1,2),(3,4),(3,6)}和other={(3,9)}为例

函数名目的示例结果
subtractByKey删除pair中键与other rdd键相同的元素rdd.subtractByKey(other){(1,2)}
join对两个rdd进行内连接rdd.join(other){(3,(4,9)),(3,(6,9))}
rightOuterJoin右外连接rdd.rightOuterJoin(other){(3,(4,9)),(3,(6,9))}
leftOuterJoin左外连接rdd.leftOuterJoin(other){(1,(2,none))(3,(4,9)),(3,(6,9))}
cogroup将两个RDD中拥有相同键的数据分组到一起rdd.cogroup(other){(1,([2],[])),(3,([4,6],[9]))}

同时pairrdd也支持普通RDD所支持的函数,传送门,例如

#对值进行筛选
result = pair.filter(lambda x:len(x)>20)

聚合操作

pair RDD提供的针对键的转化操作,类似以基础RDD的fold(),combine(),reduce()等行动操作。

reducceByKey()

#计算键对应的平均值
rdd.mapValues(lambda x :(x,1)),reduceByKey(lambda x,y:(x[0]+y[0],x[1]+y[1]))

foldByKey()

类似于上一个,但需要初始值

combineByKey()

combinByKey()会遍历所有分区中的元素,包含3个过程:

  • 如果是一个新的元素,使用createCombiner()函数创建该键对应的累加器的初始值,这一过程在每一个分区都发生。
  • 如果是已经遇到的键,使用mergeValue()方法将该键对应的累加器的当前值于新的值进行合并
  • 因为每个分区都是独立进行处理的,同一个键可能有多个累加器,所以需要使用用户提供的mergeCombiner()方法将各个分区的结果进行合并。
sumCount = num.combineByKey((lambda x: (x,1),
							(lambda x,y: (x[0]+y,x[1]+1)),
							(lambda x,y: (x[0]+y[0],x[1]+y[1]))))

并行度调优

spark始终尝试根据集群大小来推断出一个有意义的默认值来确认分区数,但是有时需要我们主动调优。

data = [('a',3),('b',4),('a',1)]
sc.parallelize(data).reduceByKey(lambda x,y: x +y ) # 默认
sc.parallelize(data).reduceByKey(lambda x,y: x +y, 10) # 自定义并行度

数据分组

groupByKey() 对当个RDD进行分组结果为 [(k,[V])]
cogroup() 对多个rdd进行分组结果为[(K,([V1],[V2]))]

连接

见上表

数据排序

sortByKey() 使用参数ascending来选择正序还是倒序。

行动操作

以键值对{(1,2),(3,4),(3,6)}为例

函数名目的示例结果
countByKey()对键进行统计rdd.countByKey(){(1,1),(3,2)}
collectAsMap()将结果以映射表的形式返回,以便于查询rdd.collectAsMap()map{(1,2),(3,6)}
lookup(key)返回对应键的所有值rdd.lookup(1)[2]

数据分区

对数据集在节点间的分区进行控制,在分布式程序中节点之间的通信代价很大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值