Spark学习——键值对RDD (python版)

键值对 RDD 的创建

from pyspark import SparkConf ,SparkContext

conf = SparkConf().setMaster("local").setAppName("RDDKeyAndValue")
sc = SparkContext(conf= conf)

第一种创建方式:从文件中加载
可以采用多种方式创建键值对 RDD ,其中一种主要方式是使用 map() 函数来实现

# 第一种创建方式:从文件中加载
# 可以采用多种方式创建键值对 RDD ,其中一种主要方式是使用 map() 函数来实现
lines = sc.textFile("file:///home/hadoop/MyTmp/sparkwordcount.txt")
pairRDD = lines.flatMap(lambda line:line.split(" ")).map(lambda word:(word,1))
pairRDD.foreach(print)

运行结果:
在这里插入图片描述

# 第二种创建方式:通过并行集合(列表)创建 RDD

# 第二种创建方式:通过并行集合(列表)创建 RDD
list = ["hadoop","spark","Hive","spark"]
rdd = sc.parallelize(list)
pairRDD = rdd.map(lambda word:(word,1))
pairRDD.foreach(print)

运行结果:
在这里插入图片描述

常用的键值对 RDD 转换操作

函数名目的
reduceByKey(func)合并具有相同键的值
groupByKey()对具有相同键的值进行分组
combineByKey(createCombine,mergeValue,mergeCombiners,partitioner)使用不同的返回类型合并具有相同键的值
mapValues(func)对pairRDD 中的每个值应用一个函数而不改变键
flatMapValues(func)对pairRDD中的每个值应用一个返回迭代器的函数,然后对返回的每个元素都生成一个对应原键的键值对记录,通常用于符号化
keys()返回一个仅包含键的RDD
alues()返回一个仅包含值的RDD
sortByKey()返回一个根据键排序的RDD

reduceByKey(func) 使用func函数合并具有相同键的值

# reduceByKey(func) Demo
pairRDD = sc.parallelize([("Hadoop",1),("Spark",1),("Hive",1),("Spark",1)])
pairRDD.reduceByKey(lambda a,b:a+b)
pairRDD.foreach(print)

运行结果如下:
在这里插入图片描述

**groupByKey()**对具有相同键的值进行分组

list = [("spark",1),("spark",2),("hadoop",3),("hadoop",4)]
pairRDD = sc.parallelize(list)
print("result1:",pairRDD.groupByKey())
print("*"*30)
pairRDD.groupByKey().foreach(print)

运行结果如下:
在这里插入图片描述
reduceByKey 和 groupByKey 的区别

  • reduceByKey 用于对每个 key 对应的多个 value 进行merge 操作,最重要的是它能够在本地先进行 merge
    操作,并且 merge 操作可以通过函数自定义
  • groupByKey 也是对每个 key 进行操作,但只生成一个sequence , groupByKey 本身不能自定义函数,需要先用
    groupByKey 生成 RDD ,然后才能对此 RDD 通过map 进行自定义函数操作

keys 只会把 Pair RDD 中的 key 返回形成一个新的 RDD

# keys 只会把 Pair RDD 中的 key 返回形成一个新的 RDD
list = [("Hadoop",1),("Spark",1),("Hive",1),("Spark",1)]
pairRDD = sc.parallelize(list)
pairRDD.keys().foreach(print)

运行结果:
在这里插入图片描述
values 只会把 Pair RDD 中的 value 返回形成一个新的 RDD

# values 只会把 Pair RDD 中的 value 返回形成一个新的 RDD 。
list = [("Hadoop",1),("Spark",1),("Hive",1),("Spark",1)]
pairRDD = sc.parallelize(list)
pairRDD.values().foreach(print)

运行结果:
在这里插入图片描述
sortByKey() 的功能是返回一个根据键排序的 RDD

# sortByKey() 的功能是返回一个根据键排序的 RDD
list = [("Hadoop",1),("Spark",1),("Hive",1),("Spark",1)]
pairRDD = sc.parallelize(list)
pairRDD.foreach(print)
print("*"*20)
pairRDD.sortByKey().foreach(print)

运行结果如下:
在这里插入图片描述

mapValues(func) 对键值对 RDD 中的每个 value 都应用一个函数,但是, key 不会发生变化

# mapValues(func)
# 对键值对 RDD 中的每个 value 都应用一个函数,但是, key 不会发生变化
list = [("Hadoop",1),("Spark",1),("Hive",1),("Spark",1)]
pairRDD = sc.parallelize(list)
pairRDD1 = pairRDD.mapValues(lambda x:x+1)
pairRDD1.foreach(print)

运行结果如下:
在这里插入图片描述

针对两个pairRDD 的转化操作
rdd={(1,2),(3,4),(3,6)} otherRDD ={(3,9)}

函数名目的示例结果
subtractByKey()删掉rdd中键与ohterRDD 中的键相同的元素rdd.subtractByKey(otherRDD){(1,2)}
join对两个RDD 进行内连接rdd.join(otherRDD){3,(4,9),(3,(6,9))}

**subtractByKey() 删掉rdd中键与ohterRDD 中的键相同的元素 **

pairRDD1 = sc.parallelize([("spark",1),("spark",2),("hadoop",3),("hadoop",5)])
pairRDD2 = sc.parallelize([("spark","fast")])
pairRDD3 = pairRDD1.subtractByKey(pairRDD2)
pairRDD3.foreach(print)

结果如下:
在这里插入图片描述

join 就表示内连接。对于内连接,对于给定的两个输入数据集 (K,V1) 和 (K,V2) ,只有在两个数据集中都存在的 key 才会被输出,最终得到一个 (K,(V1,V2)) 类型的数据集

# join
# join 就表示内连接。对于内连接,对于给定的两个输入数据集 (K,V1) 和 (K,V2) ,只有在两个数据集中都存在的 key 才会被输出,最终得到一个 (K,(V1,V2)) 类型的数据集
pairRDD1 = sc.parallelize([("spark",1),("spark",2),("hadoop",3),("hadoop",5)])
pairRDD2 = sc.parallelize([("spark","fast")])
pairRDD3 = pairRDD1.join(pairRDD2)
pairRDD3.foreach(print)

结果如下:
在这里插入图片描述

一个综合实例

题目:给定一组键值对 (“spark”,2),(“hadoop”,6),(“hadoop”,4),(“spark”,6) ,键值对的 key 表示图书名称, value 表示某天图书销量,请计算每个键对应的平均值,也就是计算每种图书的每天平均销量。

rdd = sc.parallelize([("spark",2),("hadoop",6),("hadoop",4),("spark",6)])
rddResult = rdd.mapValues(lambda x:(x,1)).\
    reduceByKey(lambda x,y:(x[0]+y[0],x[1]+y[1])).\
    mapValues(lambda x:x[0]/x[1])
print(rddResult.collect())
                                                          

运行结果下:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值