pairRDD是很多程序的构成要素,因为他们提供了一些并行操作各个键或跨节点重新进行数据分组的操作接口。
下面,先给出一个WordCount.py
from pyspark import SparkContext
sc = SparkContext( 'local[*]', 'test')
lines = sc.textFile("hdfs://Master:9000/README.md")
pairRDD = lines.flatMap(lambda line : line.split(" ")).map(lambda word :(word,1)).reduceByKey(lambda a,b :a+b)
pairRDD.foreach(print)
在Spark中会有许多种创建pairRDD的方式,我们会在接下来学习数据的读取和保存的时候会了解,很多存储键值对的数据格式会在读取的时候直接返回其键值对数据组成的pairRDD。此外,当需要把一个普通的RDD转换成pairRDD时,可以使用map()函数来实现。
常用的键值对转换操作包括reduceByKey()、groupByKey()、sortByKey()、join()、cogroup()等,下面我们通过实例来介绍。
map():
from pyspark import SparkContext
sc = SparkContext( 'local[*]', 'test')
list = ["hadoop","spark","hive","spark","mapreduce"]
rdd = sc.parallelize(list)
pairRDD = rdd.map(lambda word:(word,1))
pairRDD.foreach(print)
结果:
('hadoop', 1)
('spark', 1)
('spark', 1)
('mapreduce', 1)
('hive', 1)
reduceByKey()
pairRDD.reduceByKey(lambda a,b:a+b).foreach(print)
结果:
('spark', 2)
('hive', 1)
('hadoop', 1)
('mapreduce', 1)
groupByKey()
pairRDD.reduceByKey(lambda a,b:a+b).foreach(print)
结果:
('hive', )
('hadoop', )
('spark', )
('mapreduce', )
Keys()
pairRDD.keys().foreach(print)
结果:
spark
hadoop
hive
spark
mapreduce
values()
pairRDD.values().foreach(print)
结果:
1
1
1
1
1
sortByKeys()
pairRDD.sortByKey().foreach(print)
结果:
('hadoop', 1)
('hive', 1)
('mapreduce', 1)
('spark', 1)
('spark', 1)
我们只想对键值对RDD的value部分进行处理,而不是同时对key和value进行处理。对于这种情形,Spark提供mapValues(func),它的功能是,对键值对RDD中的每个value都应用一个函数,但是,key不会发生变化。
pairRDD.mapValues(lambda x : x+1).foreach(print)
# ('spark', 2)
# ('hadoop', 2)
# ('hive', 2)
# ('spark', 2)
# ('mapreduce', 2)
join(连接)操作是键值对常用的操作。“连接”(join)这个概念来自于关系数据库领域,因此,join的类型也和关系数据库中的join一样,包括内连接(join)、左外连接(leftOuterJoin)、右外连接(rightOuterJoin)等。最常用的情形是内连接,所以,join就表示内连接。
pairRDD1 = sc.parallelize([('spark',1),('spark',2),('hadoop',3),('hadoop',5)])
pairRDD2 = sc.parallelize([('spark','fast')])
pairRDD1.join(pairRDD2).foreach(print)
# ('spark', (1, 'fast'))
# ('spark', (2, 'fast'))
常用键值对的行动操作:以键值对集合{(1,2),(3,4),(3,6)}为例
countByKey() 对每个键对应的元素分别计数 rdd.countByKey() {(1,1),(3,2)}
collectAsMap() 将结果以映射表的形式返回,以便查询 rdd.collectAsMap() {1: 2, 3: 6}
lookup(key) 返回给定键对应的所有值 rdd.lookup(3) [4, 6]