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. 计算机基础 python入门

    1.计算机基础 计算机组成: 输入输出设备内. 存储器 .cpu .电源 .显卡 中央处理器(cpu) 处理各种数据 相当于人的大脑 内存 存储数据 相当于临时记忆 硬盘 存储数据 相当于人的永久记忆 ...

  2. GIL全局解释器锁、死锁、递归锁、线程队列

    目录 GIL全局解释锁 多线程的作用 测试计算密集型 IO密集型 死锁现象 递归锁 信号量(了解) 线程队列 GIL全局解释锁 GIL本质上是一个互斥锁. GIL是为了阻止同一个进程内多个进程同时执行 ...

  3. Flask—好的博客

    https://www.cnblogs.com/cwp-bg/p/8892403.html https://www.cnblogs.com/ExMan/p/9825710.html https://w ...

  4. python踩坑系列之导入包时下划红线及报错“No module named”问题

    python踩坑系列之导入包时下划红线及报错“No module named”问题 使用pycharm编写Python时,自己写了一个包(commontool),在同级另一个路径下(fileshand ...

  5. Pwnable-cmd1

    ssh cmd1@pwnable.kr -p2222 (pw:guest) 先看一下c的源码 #include <stdio.h> #include <string.h> in ...

  6. input 控件常用属性

  7. 最短路问题的三种算法&模板

    最短路算法&模板 最短路问题是图论的基础问题.本篇随笔就图论中最短路问题进行剖析,讲解常用的三种最短路算法:Floyd算法.Dijkstra算法及SPFA算法,并给出三种算法的模板.流畅阅读本 ...

  8. hdu6468 dfs剪枝 or char数组 or 构造

    http://acm.hdu.edu.cn/showproblem.php?pid=6468 题意 有一个序列,是1到n的一种排列,排列的顺序是字典序小的在前,那么第k个数字是什么?(\(1 \leq ...

  9. P2186 小Z的函数栈

    有点恶心的模拟(代码写整齐一点不就好了) 以下情况算错: 1.运行中有数的绝对值大于1000000000 2.除以和取模的时候第一个数为0 3.取栈顶元素时栈内元素不够 上代码 #include< ...

  10. 【12月13日】A股ROE最高排名

    个股滚动ROE = 最近4个季度的归母净利润 / ((期初归母净资产 + 期末归母净资产) / 2). 查看更多个股ROE最高排名 中公教育(SZ002607) - ROE_TTM:92.66% - ...