TransformationDemo.scala


import org.apache.spark.{HashPartitioner, SparkConf, SparkContext} import scala.collection.mutable.ListBuffer object TransformationDemo extends App { val sparkConf = new SparkConf().setMaster("local").setAppName("TransformationDemo")
val sc = new SparkContext(sparkConf) /** map */
def map = {
val list = List("小黄", "小白", "小蓝")
val listRDD = sc.parallelize(list)
listRDD.map(("hello", _)).foreach(println)
} // map
// (hello,小黄)
// (hello,小白)
// (hello,小蓝) /** flatMap */
def flatMap = {
val list = List("小黄", "小白", "小蓝")
val listRDD = sc.parallelize(list)
listRDD.flatMap(_.split(",")).map(("hello", _)).foreach(println)
} // flatMap
// (hello,小黄)
// (hello,小白)
// (hello,小蓝) /**
* mapPartitions
*
* map:
* 一条数据一条数据的处理(数据库、文件系统等)
* mapPartitions:
* 一次获取的是一个分区的数据(hdfs)
* 正常情况下,mapPartitions是一个高性能的算子
* 因为每次处理的是一个分区的数据,减少了去获取数据的次数。
*
* 但是,如果我们的分区如果设置得不合理,有可能导致每个分区里面的数据量过大。
*/
def mapPartitions = {
val list = List(1, 2, 3, 4, 5, 6)
val listRDD = sc.parallelize(list) listRDD.mapPartitions(iterator => {
val newList: ListBuffer[String] = ListBuffer()
while (iterator.hasNext) {
newList.append(s"hello ${iterator.next()}")
}
newList.toIterator
}).foreach(println(_))
} // mapPartitions
// hello 1
// hello 2
// hello 3
// hello 4
// hello 5
// hello 6 /**
* mapPartitionsWithIndex
* 每次获取和处理的就是一个分区的数据,并且可获知处理的分区的分区号
*
*/
def mapPartitionsWithIndex = {
val list = List(1, 2, 3, 4, 5, 6, 7, 8)
val listRDD = sc.parallelize(list) listRDD.mapPartitionsWithIndex((index, iterator) => {
val listBuffer: ListBuffer[String] = new ListBuffer()
while (iterator.hasNext) {
// listBuffer.append(s"${index}\t_${iterator.next()}")
listBuffer.append(f"${index}\t_${iterator.next().toFloat}%3.2f")
// listBuffer.append(raw"${index}\t${iterator.next()}")
}
listBuffer.iterator
}, true)
.foreach(println(_))
} mapPartitionsWithIndex // ------------------------------------------
// scala中插值器 s f raw ,它们都定义在 StringContext.scala 中
// s: 解析\t \n等特殊符号
// f: 格式化输出 (默认格式是 s)
// raw: 不解析\t \n等特殊符号
// ${}内可写任意字符串 // s f raw
// 0 _1 0 _1.00 0\t1
// 0 _2 0 _2.00 0\t2
// 0 _3 0 _3.00 0\t3
// 0 _4 0 _4.00 0\t4
// 0 _5 0 _5.00 0\t5
// 0 _6 0 _6.00 0\t6
// 0 _7 0 _7.00 0\t7
// 0 _8 0 _8.00 0\t8
// ------------------------------------------ /**
* reduce其实就是将RDD中的所有元素进行合并,当运行call方法时,会传入两个参数,
* 在call方法中将两个参数合并后返回,而这个返回值会和一个新的RDD中的元素再次传入call方法中,
* 继续合并,直到合并到只剩下一个元素时。
*/
def reduce = {
val list = List(1, 2, 3, 4, 5, 6)
val listRDD = sc.parallelize(list)
println(listRDD.reduce(_ + _))
} // reduce
// 21 /**
* reduceByKey仅将RDD中所有key-value键值对 中 key值相同的value进行合并
*/
def reduceByKey = {
val list = List(("小白", 1), ("小灰", 2), ("小灰", 3), ("小白", 4), ("小白", 5))
val listRDD = sc.parallelize(list)
listRDD.reduceByKey(_ + _).foreach(tuple => println(s"name: ${tuple._1} -> ${tuple._2}"))
} // reduceByKey
// name: 小白 -> 10
// name: 小灰 -> 5 /** 累加 */
def union = {
val list1 = List(1, 2, 3, 4)
val list2 = List(3, 4, 5, 6)
val rdd1 = sc.parallelize(list1)
val rdd2 = sc.parallelize(list2) rdd1.union(rdd2).foreach(x => print(s"$x ")) //.foreach(println)
} // union()
// name: 小白 -> 10
// name: 小灰 -> 5 /**
* groupByKey
* union只是将两个RDD简单的累加在一起,而join则不一样,join类似与hadoop中的combin操作,只是少了排序这一段
* groupByKey,因为join可以理解为union与groupByKey的结合:
* groupByKey是将RDD中的元素进行分组,组名是call方法中的返回值
*
* 即groupByKey是将PairRDD中拥有相同key值得元素归为一组。
*/
def groupByKey = {
val list = List(("Spark", "sparkSQL"), ("Hadoop", "YARN"), ("Spark", "sparkStreming"), ("Hadoop", "HDFS"))
val listRDD = sc.parallelize(list)
val groupByKeyRDD = listRDD.groupByKey()
groupByKeyRDD.foreach(t => {
val name = t._1
val iterator = t._2.iterator
var include = ""
while (iterator.hasNext) include = include + iterator.next() + " "
println(s"name: $name include: $include")
})
} // groupByKey
// name: Spark include: sparkSQL sparkStreming
// name: Hadoop include: YARN HDFS /** 连接 */
def join = {
val list1 = List((1, "小白"), (2, "小灰"), (3, "小蓝"))
val list2 = List((1, 99), (2, 98), (3, 97))
val list1RDD = sc.parallelize(list1)
val list2RDD = sc.parallelize(list2) val joinRDD = list2RDD.join(list1RDD)
joinRDD.foreach(t => println(s"学号: ${t._1} 姓名: ${t._2._1} 成绩: ${t._2._2}"))
} // join()
// list1RDD.join(list2RDD) list2RDD.join(list1RDD)
// 学号: 1 姓名: 小白 成绩: 99 学号: 1 姓名: 99 成绩: 小白
// 学号: 3 姓名: 小蓝 成绩: 97 学号: 3 姓名: 97 成绩: 小蓝
// 学号: 2 姓名: 小灰 成绩: 98 学号: 2 姓名: 98 成绩: 小灰 /** 抽样 */
def sample = {
val list = 1.to(100)
val listRDD = sc.parallelize(list)
listRDD.sample(false, 0.1, 0).foreach(x => print(s"$x ")) //.foreach(println)
} // sample()
// 10 39 41 53 54 58 60 80 89 98 /** 笛卡尔积 */
def cartesian = {
val list1 = List("A", "B")
val list2 = List(1, 2, 3)
val list1RDD = sc.parallelize(list1)
val list2RDD = sc.parallelize(list2) list2RDD.cartesian(list1RDD).foreach(x => println(s"${x._1} -> ${x._2}"))
} // cartesian
// list1RDD.cartesian(list2RDD) list2RDD.cartesian(list1RDD)
// A -> 1 1 -> A
// A -> 2 1 -> B
// A -> 3 2 -> A
// B -> 1 2 -> B
// B -> 2 3 -> A
// B -> 3 3 -> B /** 过滤 */
def filter = {
val list = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val listRDD = sc.parallelize(list)
listRDD.filter(_ % 2 == 0).foreach(x => print(s"$x "))
} // filter
// 2 4 6 8 10 /** 去重 */
def distinct = {
val list = List(1, 1, 2, 2, 3, 4, 5)
sc.parallelize(list).distinct().foreach(x => print(s"$x "))
} // distinct
// 4 1 3 5 2 /** 交叉点 */
def intersect = {
val list1 = List(1, 2, 3, 4)
val list2 = List(3, 4, 5, 6)
val list1RDD = sc.parallelize(list1)
val list2RDD = sc.parallelize(list2)
list1RDD.intersection(list2RDD).foreach(x => print(s"$x "))
} // intersect
// list1RDD.intersection(list2RDD) list2RDD.intersection(list1RDD)
// 4 3 4 3 /**
* 分区数由 多 -> 少
*
* 默认分区数由parallelize中的第二个参数 numSlices控制
*/
def coalesce = {
val list = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
sc.parallelize(list, 5).coalesce(5).foreach(x => print(s"$x "))
} // coalesce
// ------------------------------------------------------------------------------------
// numSlicens = 3
// coalesce(1) coalesce(2) coalesce(3) coalesce(4)....
// 1 2 3 4 5 6 7 8 9 1 2 3 1 2 3
// 4 5 6 7 8 9 4 5 6
// 7 8 9 // numSliens = 5
// coalesce(4) coalesce(5) coalesce(6)... coalesce(1) coalesce(2) coalesce(3)
// 1 1
// 2 3 2 3 1、2、3的结果同上
// 4 5 4 5
// 6 7 8 9 6 7
// 8 9
// ------------------------------------------------------------------------------------ /**
* 进行重分区
* 解决问题 本区数少 -> 增加分区数
*
* 提高并行度
* 可以绝对控制parallelize中的numSlices数量
*/
def replication = {
val list = List(1, 2, 3, 4)
sc.parallelize(list, 1).repartition(3).foreach(x => print(s"$x "))
} // replication
// ---------------------------------------
// numSlicens = 1
// repartition(1) repartition(3)
// 1 3 3
// 2 4 1 4
// 2
// --------------------------------------- /**
* repartitionAndSortWithinPartitions
* 此函数是repartition函数的变种,与repartition函数不通的是,
* 此函数在给定的partitioner内部进行排序,性能比repartition要高
*
* 分区数量由 HashPartitioner 来控制
*/
def repartitionAndSortWithinPartitions = {
val list = List(1, 4, 55, 66, 33, 48, 23)
val listRDD = sc.parallelize(list, 1)
listRDD.map(x => (x, x))
.repartitionAndSortWithinPartitions(new HashPartitioner(4))
.mapPartitionsWithIndex((index, iterator) => {
val listBuffer: ListBuffer[String] = new ListBuffer
while (iterator.hasNext) {
// listBuffer.append(s"$index${iterator.next()}")
listBuffer.append(index + "" + iterator.next())
}
listBuffer.iterator
}, false)
.foreach(x => print(s"$x "))
} // repartitionAndSortWithinPartitions
// ------------------------------------------------------------
// numSlices = 1
// .repartitionAndSortWithinPartitions(new HashPartitioner(2))
// 0(4,4) 0(48,48) 0(66,66)
// 1(1,1) 1(23,23) 1(33,33) 1(55,55) // .repartitionAndSortWithinPartitions(new HashPartitioner(3))
// 0(33,33) 0(48,48) 0(66,66)
// 1(1,1) 1(4,4) 1(55,55)
// 2(23,23) // .repartitionAndSortWithinPartitions(new HashPartitioner(4))
// 0(4,4) 0(48,48)
// 1(1,1) 1(33,33)
// 2(66,66)
// 3(23,23) 3(55,55)
// ------------------------------------------------------------ /**
* 对两个RDD中的KV元素,每个RDD中相同key中的元素分别聚合成一个集合。
* 与reduceByKey不同的是针对两个RDD中相同的key的元素进行合并。
*/
def cogroup = {
val list1 = List((1, "www"), (2, "bbs"))
val list2 = List((1, "spark"), (2, "spark"), (3, "fink"))
val list3 = List((1, "org"), (2, "org"), (3, "com")) val list1RDD = sc.parallelize(list1)
val list2RDD = sc.parallelize(list2)
val list3RDD = sc.parallelize(list3) list1RDD.cogroup(list2RDD, list3RDD)
.foreach(tuple => println(s"${tuple._1} ${tuple._2._1} ${tuple._2._2} ${tuple._2._3}"))
} // cogroup
// ------------------------------------------------------------
// list1RDD.cogroup(list2RDD,list3RDD)
// 1 CompactBuffer(www) CompactBuffer(spark) CompactBuffer(org)
// 3 CompactBuffer() CompactBuffer(fink) CompactBuffer(com)
// 2 CompactBuffer(bbs) CompactBuffer(spark) CompactBuffer(org)
// ------------------------------------------------------------ /**
* sortByKey函数作用与Key-Value形式的RDD,并对Key进行排序
* 默认为true,升序; flase,降序
*
*/
def sortByKey = {
val list = List((99, "小白"), (44, "小紫"), (55, "小黑"), (22, "小蓝"))
sc.parallelize(list).sortByKey(false)
.foreach(tuple => println(s"${tuple._1} -> ${tuple._2}"))
} // sortByKey
// ------------------------------------------------------------
// sortByKey(false)降序 sortByKey() 默认为true,升序
// 99 -> 小白 22 -> 小蓝
// 55 -> 小黑 44 -> 小紫
// 44 -> 小紫 55 -> 小黑
// 22 -> 小蓝 99 -> 小白
// ------------------------------------------------------------ /**
* aggregateByKey
* aggregateByKey函数对PairRDD中相同Key的值进行聚合操作,在聚合过程汇总同样使用了一个中立的初始值。
* 和aggregateByKey函数类似,aggregateByKey返回值的类型不需要和RDD中value的类型一致。
* 因为aggregateByKey是对相同Key中的值进行聚合操作,所以aggregateByKey函数最终返回的类型还是Pair RDD,
* 对应的结果是Key和聚合好的值;而aggregate函数直接是返回非RDD的结果,这点需要注意。
* 在实现过程中,定义了三个aggregateByKey函数原型,但最终调用的aggregateByKey函数都一致。
*
* 可设置中立值
*/
def aggregateByKey = {
val list = List("hello,world", "hello,spark")
sc.parallelize(list).flatMap(_.split(",")).map((_, 1)).aggregateByKey(0)(_ + _, _ + _).foreach(tuple => println(s"${tuple._1} -> ${tuple._2}"))
} // aggregateByKey
// aggregateByKey(0) aggregateByKey(10)
// spark -> 1 spark -> 11
// hello -> 2 hello -> 12
// world -> 1 world -> 11 //todo.. sc.stop()
}

RDD算子的使用的更多相关文章

  1. RDD算子

    RDD算子 #常用Transformation(即转换,延迟加载) #通过并行化scala集合创建RDD val rdd1 = sc.parallelize(Array(1,2,3,4,5,6,7,8 ...

  2. RDD 算子补充

    一.RDD算子补充 1.mapPartitions         mapPartitions的输入函数作用于每个分区, 也就是把每个分区中的内容作为整体来处理.   (map是把每一行) mapPa ...

  3. RDD算子、RDD依赖关系

    RDD:弹性分布式数据集, 是分布式内存的一个抽象概念 RDD:1.一个分区的集合, 2.是计算每个分区的函数 ,    3.RDD之间有依赖关系 4.一个对于key-value的RDD的Partit ...

  4. spark教程(四)-SparkContext 和 RDD 算子

    SparkContext SparkContext 是在 spark 库中定义的一个类,作为 spark 库的入口点: 它表示连接到 spark,在进行 spark 操作之前必须先创建一个 Spark ...

  5. Spark性能调优-RDD算子调优篇(深度好文,面试常问,建议收藏)

    RDD算子调优 不废话,直接进入正题! 1. RDD复用 在对RDD进行算子时,要避免相同的算子和计算逻辑之下对RDD进行重复的计算,如下图所示: 对上图中的RDD计算架构进行修改,得到如下图所示的优 ...

  6. Spark中普通集合与RDD算子的sortBy()有什么区别

    分别观察一下集合与算子的sortBy()的参数列表 普通集合的sortBy() RDD算子的sortBy() 结论:普通集合的sortBy就没有false参数,也就是说只能默认的升序排. 如果需要对普 ...

  7. Spark RDD算子介绍

    Spark学习笔记总结 01. Spark基础 1. 介绍 Spark可以用于批处理.交互式查询(Spark SQL).实时流处理(Spark Streaming).机器学习(Spark MLlib) ...

  8. 大数据入门第二十二天——spark(二)RDD算子(2)与spark其它特性

    一.JdbcRDD与关系型数据库交互 虽然略显鸡肋,但这里还是记录一下(点开JdbcRDD可以看到限制比较死,基本是鸡肋.但好在我们可以通过自定义的JdbcRDD来帮助我们完成与关系型数据库的交互.这 ...

  9. 大数据入门第二十二天——spark(二)RDD算子(1)

    一.RDD概述 1.什么是RDD RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可并行计算的 ...

随机推荐

  1. ubuntu 改键

    参考: https://www.jianshu.com/p/9411ee427cfd https://www.cnblogs.com/zhengchl/archive/2012/08/25/26557 ...

  2. 卷积层输出feature maps尺寸的计算

    默认feature maps的宽和高相等. 常规卷积 输入的feature maps尺寸为i,卷积核的尺寸为k,stride为s,padding为p,则输出的feature maps的尺寸o为 当pa ...

  3. 开源敏捷测试管理& 开源BUG跟踪管理软件itest(爱测试) V3.3.1小改紧急发布及正实现功能预告

    v3.3.1 下载地址 :itest下载 码云源码地址 https://gitee.com/itestwork/itest 开源中国  itest项目地址   https://www.oschina. ...

  4. 2.Python爬虫入门_requests

    #2019-11-23 #requests的api使用非常简单 import requests import time if __name__=='__main__': # get请求 url_get ...

  5. 01_javaSE面试题:自增变量

    开启刷面试题,都是根据视频进行刷面试题的 自增变量,只要记住两点 i++ 是先赋值后计算 ++i 是先计算后赋值 看下面的代码 int i = 1; i = i++; int j = i++; int ...

  6. CF1225A Forgetting Things

    CF1225A Forgetting Things 洛谷评测传送门 题目描述 Kolya is very absent-minded. Today his math teacher asked him ...

  7. C++ string push_back()

    函数功能: 在后面添加一项 vector头文件的push_back函数,在vector类中作用为在vector尾部加入一个数据.string中的push_back函数,作用是字符串之后插入一个字符. ...

  8. C# Windows服务创建安装卸载

    一.创建Windows服务 使用VS创建一个新的windows服务应用程序 创建完成之后 二.相关配置 修改Service1名称为StartService(可以不改,自行选择) 添加安装程序并修改配置 ...

  9. 第04组 Alpha冲刺(5/6)

    队名:new game 组长博客:戳 作业博客:戳 组员情况 鲍子涵(队长) 燃尽图 过去两天完成了哪些任务 才两天,也就是实现一些功能而已 复习了一下SuffixAutomata 接下来的计划 实现 ...

  10. 支付宝AopSdk在dotnet core下的实现

    随着项目都迁移到了dotnet core下,阿里的支付宝也需要随着项目迁移.之前在.Net Framework下用到了阿里提供的AopSdk和F2FPay两个程序集,支付宝官方提供的只支持Framew ...