当前位置: 首页 > news >正文

Spark 键值对RDD的操作

键值对RDD(Pair RDD)是指每个RDD元素都是(key,value)键值对类型,是一种常见的RDD类型,可以应用于很多的应用场景。

一、 键值对RDD的创建

键值对RDD的创建主要有两种方式:
(1)从文件中加载生成RDD;
(2)通过并行集合(数组)创建RDD。

1,从文件中加载生成RDD

首先使用textFile()方法从文件中加载数据,然后,使用map()函数转换得到相应的键值对RDD。

scala> val  lines = sc.textFile("file:///usr/local/spark/mycode/pairrdd/word.txt")
lines: org.apache.spark.rdd.RDD[String] = file:///usr/local/spark/mycode/pairrdd/ word.txtMapPartitionsRDD[1] at textFile at <console>:27 
scala> val  pairRDD = lines.flatMap(line => line.split(" ")).map(word => (word,1)) pairRDD: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[3] at map at <console>:29 
scala> pairRDD.foreach(println) 
(i,1) 
(love,1) 
(hadoop,1) 
…… 

map(word => (word,1))函数的作用是,取出RDD中的每个元素,也就是每个单词,赋值给word,然后把word转换成(word,1)的键值对形式。

2,通过并行集合(数组)创建RDD

scala> val  list = List("Hadoop","Spark","Hive","Spark")
list: List[String] = List(Hadoop, Spark, Hive, Spark)  scala> val  rdd = sc.parallelize(list) rdd: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[11] at parallelize at <console>:29  
scala> val pairRDD = rdd.map(word => (word,1)) pairRDD: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[12] at map at <console>:31 
scala> pairRDD.foreach(println) 
(Hadoop,1) 
(Spark,1) 
(Hive,1) 
(Spark,1)

二、常用的键值对转换操作

常用的键值对转换操作包括reduceByKey(func)、groupByKey()、keys、values、sortByKey()、mapValues(func)、join和combineByKey等。

1,reduceByKey(func)

reduceByKey(func)的功能是,使用func函数合并具有相同键的值。
有一个键值对RDD包含4个元素,分别是(“Hadoop”,1)、(“Spark”,1)、(“Hive”,1)和(“Spark”,1)。可以使用reduceByKey()操作,得到每个单词的出现次数,代码及其执行结果如下:

scala> pairRDD.reduceByKey((a,b)=>a+b).foreach(println)
(Spark,2)
(Hive,1)
(Hadoop,1)

2,·groupByKey()

groupByKey()的功能是,对具有相同键的值进行分组。
有四个键值对(“spark”,1)、(“spark”,2)、(“hadoop”,3)和(“hadoop”,5),采用groupByKey()后得到的结果是:(“spark”,(1,2))和(“hadoop”,(3,5)),代码及其执行结果如下:

scala> pairRDD.groupByKey()
res15: org.apache.spark.rdd.RDD[(String, Iterable[Int])] = ShuffledRDD[15] at groupByKeyat <console>:34

reduceByKey和groupByKey的区别是:reduceByKey用于对每个key对应的多个value进行聚合操作,并且聚合操作可以通过函数func进行自定义;groupByKey也是对每个key进行操作,但是,对每个key只会生成一个value-list,groupByKey本身不能自定义函数,需要先用groupByKey生成RDD,然后才能对此RDD通过map进行自定义函数操作。

3,keys()

键值对RDD每个元素都是(key,value)的形式,keys操作只会把键值对RDD中的key返回,形成一个新的RDD。

有一个键值对RDD,名称为pairRDD,包含4个元素,分别是(“Hadoop”,1)、(“Spark”,1)、(“Hive”,1)和(“Spark”,1),可以使用keys方法取出所有的key并打印出来,代码及其执行结果如下:

scala> pairRDD.keys
res17: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[17] at keys at <console>:34 
scala> pairRDD.keys.foreach(println) 
Hadoop 
Spark 
Hive 
Spark

4,values()

values操作只会把键值对RDD中的value返回,形成一个新的RDD。

有一个键值对RDD,名称为pairRDD,包含4个元素,分别是(“Hadoop”,1)、(“Spark”,1)、(“Hive”,1)和(“Spark”,1),可以使用values方法取出所有的value并打印出来,代码及其执行结果如下:

scala> pairRDD.values
res0: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[2] at values at <console>:34  
scala> pairRDD.values.foreach(println) 
1 
1 
1 
1

5,sortByKey()

sortByKey()的功能是返回一个根据key排序的RDD。

有一个键值对RDD,名称为pairRDD,包含4个元素,分别是(“Hadoop”,1)、(“Spark”,1)、(“Hive”,1)和(“Spark”,1),使用sortByKey()的效果如下:

scala> pairRDD.sortByKey()
res0: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[2] at sortByKey at <console>:34 
scala> pairRDD.sortByKey().foreach(println) 
(Hadoop,1) 
(Hive,1) 
(Spark,1) 
(Spark,1)

6,sortBy()

sortByKey()的功能是返回一个根据key排序的RDD,而sortBy()则可以根据其他字段进行排序。

scala> val  d1 = sc.parallelize(Array(("c",8),("b",25),("c",17),("a",42),("b",4),("d",9),("e",17),("c",2),("f",29),("g",21),("b",9))) 
scala> d1.reduceByKey(_+_).sortByKey(false).collect res2: Array[(String, Int)] = Array((g,21),(f,29),(e,17),(d,9),(c,27),(b,38),(a,42))

sortByKey(false)括号中的参数false表示按照降序排序,如果没有提供参数false,则默认采用升序排序。从上面排序后的效果可以看出,所有键值对都按照key的降序进行了排序,因此输出Array((g,21),(f,29),(e,17),(d,9),(c,27),(b,38),(a,42))。

7,mapValues(func)

mapValues(func)对键值对RDD中的每个value都应用一个函数,但是,key不会发生变化。
有一个键值对RDD,名称为pairRDD,包含4个元素,分别是(“Hadoop”,1)、(“Spark”,1)、(“Hive”,1)和(“Spark”,1),下面使用mapValues()操作把所有RDD元素的value都增加1:

scala> pairRDD.mapValues(x => x+1)res2: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[4] at mapValues at <console>:34 scala> pairRDD.mapValues(x => x+1).foreach(println) (Hadoop,2) (Spark,2) (Hive,2) (Spark,2)

8,join()

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

scala> val  pairRDD1 = sc.| parallelize(Array(("spark",1),("spark",2),("hadoop",3),("hadoop",5))) 
scala> val  pairRDD2 = sc.parallelize(Array(("spark","fast"))) 
scala> pairRDD1.join(pairRDD2) 
scala> pairRDD1.join(pairRDD2).foreach(println) 
(spark,(1,fast)) 
(spark,(2,fast))

pairRDD1中的键值对(“spark”,1)和pairRDD2中的键值对(“spark”,“fast”),因为二者具有相同的key(即"spark"),所以会产生连接结果(“spark”,(1,“fast”))。

9,combineByKey()

combineByKey(createCombiner,mergeValue,mergeCombiners,partitioner,mapSideCombine)中的各个参数的含义如下:
(1)createCombiner:在第一次遇到key时创建组合器函数,将RDD数据集中的V类型值转换C类型值(V => C);
(2)mergeValue:合并值函数,再次遇到相同的Key时,将createCombiner的C类型值与这次传入的V类型值合并成一个C类型值(C,V)=>C;
(3)mergeCombiners:合并组合器函数,将C类型值两两合并成一个C类型值;
(4)partitioner:使用已有的或自定义的分区函数,默认是HashPartitioner;
(5)mapSideCombine:是否在map端进行Combine操作,默认为true。

文章来源:《Spark编程基础》 作者:林子雨

文章内容仅供学习交流,如有侵犯,联系删除哦!

http://www.lryc.cn/news/38077.html

相关文章:

  • 【SpringCloud】SpringCloud详解之Feign远程调用
  • 文档团队怎样使用GIT做版本管理
  • 【java】Java中-> 是什么意思?
  • 网络类型部分实验
  • java教程--函数式接口--lambda表达式--方法引用
  • java——代理
  • kubernetes中service探讨
  • Python3实现“美颜”功能
  • 【创建“待选项”按钮02计算坐标 Objective-C语言】
  • 自组织( Self-organization),自组织临界性(Self-organized criticality)
  • Elasticsearch:集群管理
  • 华为OD机试题 - 非严格递增连续数字序列(JavaScript)| 机考必刷
  • lc23. 合并K个升序链表
  • Java笔记029-泛型
  • 港科夜闻|香港科大与中国联通成立联合实验室,推动智慧社会研究发展
  • 制作一个简单的信用卡验证表
  • 牛客小白月赛68
  • 【id:21】【20分】A. DS单链表--类实现
  • 【实习_面试全程辅导分享】简历篇
  • 【学习笔记】CF1305 Kuroni and Antihype
  • json-server单独使用或者在react中进行使用
  • 【6G 新技术】6G数据面介绍
  • 【AI绘图学习笔记】深度前馈网络(一)
  • 目标检测笔记合集
  • 《计算机网络》期末复习笔记
  • linux下安装SonarQube
  • MyBatis-Plus(狂神)
  • Python3实现写作
  • UEFI实战--------HII之uni文件
  • 基于Spring Boot集成MyBatis-3.5.9操作数据库