import org.apache.spark.rdd.RDD
import org.apache.spark.{Partitioner, SparkConf, SparkContext}
object Transformation {

  def main(args: Array[String]): Unit = {

    val config: SparkConf = new SparkConf().setMaster("local[*]").setAppName("Transformation")

    val sc = new SparkContext(config)

    val listRDD = sc.makeRDD(1 to 10)
val listRDD2 = sc.makeRDD(Array(List(1, 2), List(3, 4)))
val listRDD3 = sc.makeRDD(5 to 14) /***************************单value*****************************/ /**
* map(func)
* 每次处理1条数据
*/ // val mapRDD = listRDD.map(_ * 2) /**
* mapPartitions(func)
* 每次处理一组分区数据,效率高,但可能出现内存溢出(因为处理完一组分区后再释放)
*/ // val mapPartitionsRDD = listRDD.mapPartitions(datas=>{
// datas.map(data => data * 2)
// }) /**
* mapPartitionsWithIndex(func)
* 函数的输入多了分区号
*/ // val tupleRDD: RDD[(Int, String)] = listRDD.mapPartitionsWithIndex {
// case (num, datas) => {
// datas.map((_, " 分区号:" + num))
// }
// } /**
* flatMap(func)
* 将map后的数据扁平
*/ // val flatMAPRDD: RDD[Int] = listRDD2.flatMap(datas => datas) /**
* glom()
* 将一个分区的数据放在一个数组里
*/ // val glomRDD: RDD[Array[Int]] = listRDD.glom() /**
* groupBy(func)
* 按照函数的返回值进行分组,分组后的数据(K:分组的key,V:分组的集合)
*/ // val groupByRDD: RDD[(Int, Iterable[Int])] = listRDD.groupBy(i => i%2)
// groupByRDD.collect().foreach(println) /**
* filter(func)
* 按照返回值为true的过滤
*/ // val filterRDD: RDD[Int] = listRDD.filter(x => x % 2 ==0)
// filterRDD.collect().foreach(println) /**
* sample(withReplacement : scala.Boolean, fraction : scala.Double, seed : scala.Long)
* 随机抽样
*/ // val sampleRDD: RDD[Int] = listRDD.sample(false, 0.4, 1)
// sampleRDD.collect().foreach(println) /**
* distinct()
* 去重,且去重后会shuffler,可以指定去重后的分区数
*/ // val distinctRDD: RDD[Int] = listRDD.distinct()
// distinctRDD.collect().foreach(println) /**
* coalesce(n)
* 缩减分区的数量,可以简单的理解为合并分区,默认,没有shuffler,可以加参数true指定shuffler
*/ // println("缩减分区前 = " + listRDD.partitions.size)
// val coalesceRDD: RDD[Int] = listRDD.coalesce(2)
// println("缩减分区前 = " + coalesceRDD.partitions.size) /**
* repartition()
* 重新分区,有shuffler。它其实就是带true的coalesce
*/ // listRDD.glom().collect().foreach(arrays => {
// println(arrays.mkString(","))
// })
// val repartitionRDD: RDD[Int] = listRDD.repartition(2)
// repartitionRDD.glom().collect().foreach(arrays => {
// println(arrays.mkString(","))
// }) /**
* sortBy(f: (T) => K,ascending: Boolean = true,numPartitions: Int = this.partitions.length))
* 根据函数排序
*/ // val sortByRDD: RDD[Int] = listRDD.sortBy(n => n % 2, false)
// sortByRDD.collect().foreach(println) /**************************双value交互*****************************/ /**
* 双value交互
* A.union(B) 对A、B合并。(不去重)
* A.subtract(B) 对A减去和B中的相同的
* A.cartesian(B) 对A、B求笛卡尔乘积
* A.zip(B) 将A、B组成(k,v),个数、分区数要相等
* A.union(B) 对A、B求并集
*/ // listRDD.union(listRDD3).collect().foreach(println)
// listRDD.subtract(listRDD3).collect().foreach(println)
// listRDD.intersection(listRDD3).collect().foreach(println)
// listRDD.cartesian(listRDD3).collect().foreach(println)
// listRDD.zip(listRDD3).collect().foreach(println) /**************************(k,v)对*******************************/ val pairRDD1: RDD[(Int, String)] = sc.parallelize(Array((1, "aa"), (1, "bb"), (3, "cc"), (3, "dd")), 4)
val pairRDD2: RDD[(String, Int)] = sc.parallelize(Array(("a", 3), ("a", 2), ("c", 4),
("b", 3), ("c", 6), ("c", 8)), 2)
val pairRDD3: RDD[(Int, String)] = sc.parallelize(Array((1, "zzz"), (3, "xxx"))) /**
* partitionBy(partitioner: Partitioner)
* 按照分区器进行分区
*/ // pairRDD1.partitionBy(new org.apache.spark.HashPartitioner(2))
// .glom().collect().foreach(arrays => {
// println(arrays.mkString(","))
// }) // pairRDD1.partitionBy(new MyPartitioner(3))
// .glom().collect().foreach(arrays => {
// println(arrays.mkString(","))
// }) /**
* groupByKey()
* 单纯把key相等的value放在一起,生成序列
*/
// pairRDD1.groupByKey().collect().foreach(println) /**
* reduceByKey(func)
* 按key聚合,并且按函数对key相等的value进行操作
*/ // pairRDD1.reduceByKey(_ + _)
// .glom().collect().foreach(arrays => {
// println(arrays.mkString(","))
// }) /**
* aggregateByKey[U: ClassTag](zeroValue: U)(seqOp: (U, V) => U, combOp: (U, U) => U)
* zeroValue:每个分区的每一个key的初始值
* seqOp:每个分区里的聚合函数
* seqOp:分区间的聚合函数
*/ // 取出每个分区相同对key的最大值,在相加
// pairRDD2.aggregateByKey(0)(math.max(_,_), _+_)
// .glom().collect().foreach(arrays => {
// println(arrays.mkString(","))
// }) /**
* foldByKey(zeroValue: V)(func: (V, V) => V)
* 其实就是aggregateByKey的简化版,seqOp和seqOp相同
*/ // pairRDD2.foldByKey(0)(_ + _)
// .glom().collect().foreach(arrays => {
// println(arrays.mkString(","))
// }) /**
* combineByKey[C](
* createCombiner: V => C,
* mergeValue: (C, V) => C,
* mergeCombiners: (C, C) => C,
* partitioner: Partitioner,
* mapSideCombine: Boolean = true,
* serializer: Serializer = null)
*
* 主要就是比aggregateByKey多了一个createCombiner,用于计算初始值
*/ // 计算相同key的value的均值
// pairRDD2.combineByKey(
// (_, 1),
// (acc:(Int, Int), v) => (acc._1 + v, acc._2 + 1),
// (acc1:(Int, Int), acc2:(Int, Int)) => (acc1._1 + acc2._1, acc1._2 + acc2._2))
// .map{case (key, value) => (key, value._1 / value._2.toDouble)}
// .collect().foreach(println) /**
* sortByKey(ascending: Boolean = true, numPartitions: Int = self.partitions.length)
* 按key排序
*/ // pairRDD1.sortByKey(true)
// .collect().foreach(println) /**
* mapValues(func)
* 只对value做转换
*/ // pairRDD1.mapValues(value => value + "|||")
// .collect().foreach(println) /**
* A.join(B, numP)
* 把key相同的value组合在一起(性能较低)
*/ // pairRDD1.join(pairRDD3)
// .collect().foreach(println) /**
* A.cogroup(B)
* (k, v1) 和 (k, v2)cogroup 后,得到(k, v1集合,v2集合)
*/ pairRDD1.cogroup(pairRDD3)
.collect().foreach(println) sc.stop() }
} // 自定义分区器
class MyPartitioner (partitions: Int) extends Partitioner {
override def numPartitions: Int = {
partitions
} override def getPartition(key: Any): Int = {
1
}
}

  //只写代码不让我发出来--忽略这一行

RDD的转换操作,分三种:单value,双value交互,(k,v)对的更多相关文章

  1. python对mysql数据库操作的三种不同方式

    首先要说一下,在这个暑期如果没有什么特殊情况,我打算用python尝试写一个考试系统,希望能在下学期的python课程实际使用,并且尽量在此之前把用到的相关技术都以分篇博客的方式分享出来,有想要交流的 ...

  2. PHP实现链式操作的三种方法详解

    这篇文章主要介绍了PHP实现链式操作的三种方法,结合实例形式分析了php链式操作的相关实现技巧与使用注意事项,需要的朋友可以参考下 本文实例讲述了PHP实现链式操作的三种方法.分享给大家供大家参考,具 ...

  3. CAD转DXF怎么转换?教你三种转换方法

    CAD图纸在我们日常生活中都是可见到的,因为CAD图纸文件的格式是多样的,在工作中就需要经常将CAD的格式进行转换.那CAD转DXF怎么转换呢?这个问题很多的小伙伴们都遇到过,下面小编就来教大家三种转 ...

  4. Spring实现初始化和销毁bean之前进行的操作,三种方式

    关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 第二 ...

  5. RDD的转换操作---RDD转换过程

    1) union(otherRDD)RDD-->UnionRDD2) groupByKey(numPartitions)RDD-->ShuffledRDD-->MapPartitio ...

  6. javascript浮点数转换成整数三种方法

    将浮点数转换成整数方法有很多,分享三种常用方法. Summary 暂时我就想到3个方法而已.如果读者想到其他好用方法,也可以交流一下 parseInt位运算符Math.floor Math.ceil ...

  7. Cortex-M 实现互斥操作的三种方法

    注:本文仅针对Cortex-M3/4 系列进行讲述. 在传统的ARM处理器架构中,常使用SWP指令来实现锁的读/写原子操作,但从ARM v6开始,读/写访问在独立的两条总线上进行,SWP指令已无法在此 ...

  8. Egret中的三种单例写法

    1 普通的单例写法 as3中也是这么个写法. 缺点:每个单例类里都要写instance和getInstance. class Single{ private static instance:Singl ...

  9. List转换Map的三种方式

    1.for循环 ... 2.使用guava Map<Long, User> maps = Maps.uniqueIndex(userList, new Function<User, ...

随机推荐

  1. jQuery-对列表的操作

    主要是通过对dom元素的增加和删除实现对数据增加和删除 <!DOCTYPE html> <html lang="en"> <head> < ...

  2. elasticsearch bulk

    情景介绍 公司2000W的数据从mysql 迁移至elasticsearch,以提供微服务.本文基于elasticsearch-py bulk操作实现数据迁移.相比于elasticsearch-dum ...

  3. SPC软控件提供商NWA的产品在各行业的应用(生命科学行业)

    在上一篇文章中,我们提到了NWA软件产品在各行业都有广泛的应用,并且就化工行业的应用展开了详细介绍.而在本文中,您将看到NWA产品在生命科学行业也扮演着不可替代的角色. Northwest Analy ...

  4. C++智能指针解析

    前言 在C++程序中,内存分为三种静态内存.栈内存.堆内存.其中静态内存和栈内存由系统进行维护,而堆内存则是由程序员自己进行维护,也就是我们在new和delete对象时,这些对象存放的区域.任何有C+ ...

  5. ROW_NUMBER()实现分页

    1. 在数据表基础上面添加一个自增的一列记录行数(虚拟的实际数据库不存在,不会影响数据库结构)的列当然也顺便起一个别名(我这里起了一个rowNum) 2.由于rowNum是一个虚拟的.若直接使用会报' ...

  6. unity常用的坐标系转换

    当调用别人的接口时,经常会有获取位置或向量的接口.遇到这些数据时,先要弄清楚现在获取的数据在哪个坐标系下的. 是否需要进行坐标系变换,一般提供的位置和向量都是在世界坐标系的,此时需要注意: ①对方的坐 ...

  7. 3 测试使用和LogCat日志

    测试概念: 1.根据是否知道源代码分: 黑盒测试:功能测试 白盒测试:编写代码进行测试 2.测试力度划分: 方法测试: 单元测试: 集成测试: 系统测试: 3.暴力程度划分: 压力测试: 冒烟测试:压 ...

  8. liteos错误处理(十一)

    1. 概述 1.1 基本概念 错误处理指用户代码发生错误时,系统调用错误处理模块的接口函数,完成上报错误信息,并调用用户自己的钩子函数,进行特定的处理. 错误处理模块实现OS内部错误码记录功能.OS内 ...

  9. 15、iptables详解

    --     http://www.netfilter.org/ http://www.iptables.org/     --参考路径 http://www.netfilter.org/docume ...

  10. ansible 模块 roles

    setup 作用,用来查看用看内部的详细信息 ansible_all_ipv4_addresses # ipv4的所有地址 ansible_all_ipv6_addresses # ipv6的所有地址 ...