Spark算子讲解(一)
1:Zip算子
def zip[U](other: RDD[U])(implicit arg0: ClassTag[U]): RDD[(T, U)]
将两个RDD做zip操作,如果当两个RDD分区数目不一样的话或每一个分区数目不一样的话则会异常。
例如:
val rdd1 = sc.parallelize(Array(1,2,3,4,5,6),2)
val rdd2 = sc.parallelize(Array(1,2,3,4,5,6),3)
rdd.zip(rdd1).collect
异常信息:
java.lang.IllegalArgumentException: Can't zip RDDs with unequal numbers of partitions: List(2, 3)
at org.apache.spark.rdd.ZippedPartitionsBaseRDD.getPartitions(ZippedPartitionsRDD.scala:57)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:252)
at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:250)
例如:
val rdd1 = sc.parallelize(Array(1,2,3,4,5,6),2)
val rdd2 = sc.parallelize(Array(1,2,3,4,5,6,7),2)
rdd.zip(rdd1).collect
异常信息:
Caused by: org.apache.spark.SparkException: Can only zip RDDs with same number of elements in each partition
2:zipPartitions
以分区为单位进行zip操作,要求分区数目相等。否则异常。
val rdd1 = sc.parallelize(Array(1,2,3,4,5,6),2)
val rdd2 = sc.parallelize(Array(1,2,3,4,5,6,7),2)
val func = (x:Iterator[Int], y:Iterator[Int])=>x.toSeq.++(y.toSeq).toIterator
rdd1.zipPartitions(rdd2)(func).collect
3:zipWithIndex
给RDD中的每一个元素添加上索引号,组成二元组。索引号从0开始并且索引号类型是Long,当RDD分区大于1个时候需要出发一个Spark Job。
4:zipWithUniqueId
var rdd1 = sc.makeRDD(Seq("A","B","C","D","E","F"),2)
//rdd1有两个分区,
rdd1.zipWithUniqueId().collect
Array[(String, Long)] = Array((A,0), (B,2), (C,4), (D,1), (E,3), (F,5))
//总分区数为2
//第一个分区第一个元素ID为0,第二个分区第一个元素ID为1
//第一个分区第二个元素ID为0+2=2,第一个分区第三个元素ID为2+2=4
//第二个分区第二个元素ID为1+2=3,第二个分区第三个元素ID为3+2=5
其实就是按照每一个的分区的每一个元素的顺序进行编号。这个算子不需要出发作业到集群运行。
5:union
RDD求并集操作,不会自动去重。
res31: Array[Int] = Array(1, 2, 3, 4, 5, 6) scala> rdd2.collect
collect collectAsync scala> rdd2.collect
res32: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7) scala> rdd1.union(rdd2).collect
collect collectAsync scala> rdd1.union(rdd2).collect
res34: Array[Int] = Array(1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7)//不去重
6:distinct
scala> unionRDD.collect
res38: Array[Int] = Array(1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7)
scala> unionRDD.distinct.collect
res39: Array[Int] = Array(4, 1, 5, 6, 2, 3, 7)
实现去重。
7:treeReduce
treeReduce有点类似于reduce函数,也不需要传入初始值,只不过这个算子使用一个多层树的形式来进行reduce操作。
scala> rdd1.collect
res42: Array[Int] = Array(1, 2, 3, 4, 5, 6) scala> rdd1.treeReduce((x,y)=>x+y)
res43: Int = 21
8:aggregate
scala> rdd1.collect
res53: Array[Int] = Array(1, 2, 3, 4, 5, 6) scala> rdd1.partitions.length
res54: Int = 2 scala> rdd1.aggregate(1)((x,y)=>x+y,(x,y)=>x+y)
res56: Int = 24 scala> rdd1.repartition(3).aggregate(1)((x,y)=>x+y,(x,y)=>x+y)
res57: Int = 25
我们设置的聚集函数的ZeroValue值是1,这个值会每一个分区聚集时候使用一次,最后在聚集所有分区时候在使用一次。
我们这里面分区内部元素计算函数是:
(x,y)=>x+y
分区之间的聚集函数:
(x,y)=>x+y
由于rdd1默认是2个分区,所以在计算两个分区时候使用两次,相当于+1,最后合并两个分区时候有使用一次,相当于再加1.所以一共加3,,即:
1+2+3+4+5+6=21,21+3 =24.另一个只因为多一个分区,所以多累加1.
9:treeAggregate
和8中聚集算子效果一样,只不过使用的是树的层次结构聚集。
10:top
返回前面n个最大元素,可以定义排序规则
11:takeSample
def takeSample(withReplacement: Boolean, num: Int, seed: Long = Utils.random.nextLong): Array[T]
随机采样,抽取num个样例。可以指定是否重复抽取,随机数种子是一个生成随机数的初始条件,可以使用系统时间戳作为种子值。
当不允许重复抽取时候,num数目大于rdd元素数目不会报错,此时只会抽取rdd的所有元素。
12:takeOrdered
def takeOrdered(num: Int)(implicit ord: Ordering[T]): Array[T]
抽取出num个个最小的元素,唯一和top区别就是top抽取大的,takeOrdered抽取小的。
13:take
def take(num: Int): Array[T]
返回num个数据,一般当数据较大的时候如果collect操作会导致Driver内存溢出,所以此时可以使用take携带少量数据到Driver。
14:subtract
def subtract(other: RDD[T]): RDD[T]
返回一个在当前RDD中且不在other中的元素所生成的RDD
15:sortBy
def sortBy[K](f: (T) ⇒ K, ascending: Boolean = true, numPartitions: Int = this.partitions.length)(implicit ord: Ordering[K], ctag: ClassTag[K]): RDD[T]
例如:
scala> rdd1.collect
res19: Array[Int] = Array(1, 2, 3, 4, 5) scala> val rdd2 = rdd1.map(x=>(x,scala.util.Random.nextInt(100),scala.util.Random.nextInt(100)))
rdd2: org.apache.spark.rdd.RDD[(Int, Int, Int)] = MapPartitionsRDD[33] at map at <console>:26 scala> rdd2.collect
collect collectAsync scala> rdd2.collect
res20: Array[(Int, Int, Int)] = Array((1,87,34), (2,5,62), (3,51,60), (4,72,33), (5,33,23)) scala> res13.sortBy(x=>x._3).collect
res21: Array[(Int, Int, Int)] = Array((3,26,12), (4,45,28), (1,12,37), (2,71,67), (5,80,96))
16:sample
def sample(withReplacement: Boolean, fraction: Double, seed: Long = Utils.random.nextLong): RDD[T]
随机采样,是否重复采样,抽取数据的百分比例。
17:repartition
def repartition(numPartitions: Int)(implicit ord: Ordering[T] = null): RDD[T]
重新创建一个只有numPartitions个分区的RDD,提高分区数或降低分区数会改变并行度,内部实现实现需要shuffle。如果需要降低RDD的分区数的话尽可能使用coalesce算子,它会避免shuffle的发生。
18:coalesce
def coalesce(numPartitions: Int, shuffle: Boolean = false, partitionCoalescer: Option[PartitionCoalescer] = Option.empty)(implicit ord: Ordering[T] = null): RDD[T]
降低原来RDD的分区数目到numPartitions个分区。例如由1000个分区降到100个分区的话,这样是一个窄依赖,因此不需要shuffle过程。
但是如果RDD原本有2个分区的话,当我们调用coalesce(5)的话,生成的RDD分区还将是2,不会增加,但是如果调用coalesce(1)的话,则会生成分区个数为1的RDD。(coalesce只会减少分区数,不会增加分区数)。
拓展:如果我们的RDD分区数为1的话,我们可以传递shuffle=true,当计算时候会进行shuflle分布到多个节点进行计算。
19:checkpoint
def checkpoint(): Unit
Mark this RDD for checkpointing. It will be saved to a file inside the checkpoint directory set with SparkContext#setCheckpointDir and all references to its parent RDDs will be removed. This function must be called before any job has been executed on this RDD. It is strongly recommended that this RDD is persisted in memory, otherwise saving it on a file will require recomputation.
20:cartesian
def cartesian[U](other: RDD[U])(implicit arg0: ClassTag[U]): RDD[(T, U)]
两个RDD生成笛卡尔积。
scala> rdd1.collect
res37: Array[Int] = Array(1, 2, 3, 4, 5) scala> rdd2.collect
res38: Array[Int] = Array(6, 7, 8, 9, 10) scala> rdd1.cartesian(rdd2).collect
res39: Array[(Int, Int)] = Array((1,6), (1,7), (2,6), (2,7), (1,8), (1,9), (1,10), (2,8), (2,9), (2,10), (3,6), (3,7), (4,6), (4,7), (5,6), (5,7), (3,8), (3,9), (3,10), (4,8), (4,9), (4,10), (5,8), (5,9), (5,10))
21:cache
def cache(): RDD.this.type
将RDD缓存,缓存级别为:MEMORY_ONLY
22:persist
def persist(): RDD.this.type
将RDD缓存,缓存级别为:MEMORY_ONLY
23:persist
def persist(newLevel: StorageLevel): RDD.this.type
指定缓存级别,在第一次被计算之后进行缓存。
24:keyBy
def keyBy[K](f: (T) ⇒ K): RDD[(K, T)]
根据函数f进行选取key,例如:
scala> rdd1.collect
res43: Array[Int] = Array(1, 2, 3, 4, 5) scala> rdd1.keyBy(x=>x*x).collect
res44: Array[(Int, Int)] = Array((1,1), (4,2), (9,3), (16,4), (25,5))
25:intersection
def intersection(other: RDD[T]): RDD[T]
求两个RDD的交集
Spark算子讲解(一)的更多相关文章
- Spark算子讲解(二)
1:glom def glom(): RDD[Array[T]] 将原RDD的元素收集到一个数组,创建一个数组类型的RDD 2:getNumPartitions final def getNumPar ...
- (转)Spark 算子系列文章
http://lxw1234.com/archives/2015/07/363.htm Spark算子:RDD基本转换操作(1)–map.flagMap.distinct Spark算子:RDD创建操 ...
- Spark算子总结及案例
spark算子大致上可分三大类算子: 1.Value数据类型的Transformation算子,这种变换不触发提交作业,针对处理的数据项是Value型的数据. 2.Key-Value数据类型的Tran ...
- UserView--第二种方式(避免第一种方式Set饱和),基于Spark算子的java代码实现
UserView--第二种方式(避免第一种方式Set饱和),基于Spark算子的java代码实现 测试数据 java代码 package com.hzf.spark.study; import ...
- UserView--第一种方式set去重,基于Spark算子的java代码实现
UserView--第一种方式set去重,基于Spark算子的java代码实现 测试数据 java代码 package com.hzf.spark.study; import java.util.Ha ...
- spark算子之DataFrame和DataSet
前言 传统的RDD相对于mapreduce和storm提供了丰富强大的算子.在spark慢慢步入DataFrame到DataSet的今天,在算子的类型基本不变的情况下,这两个数据集提供了更为强大的的功 ...
- Spark SQL讲解
Spark SQL讲解 Spark SQL是支持在Spark中使用Sql.HiveSql.Scala中的关系型查询表达式.它的核心组件是一个新增的RDD类型SchemaRDD,它把行对象用一个Sche ...
- Spark算子总结(带案例)
Spark算子总结(带案例) spark算子大致上可分三大类算子: 1.Value数据类型的Transformation算子,这种变换不触发提交作业,针对处理的数据项是Value型的数据. 2.Key ...
- Spark算子---实战应用
Spark算子实战应用 数据集 :http://grouplens.org/datasets/movielens/ MovieLens 1M Datase 相关数据文件 : users.dat --- ...
随机推荐
- javascript编程解决黑化的牛牛问题
问题描述 时间限制:1秒 空间限制:32768K 牛牛变得黑化了,想要摧毁掉地球.但他忘记了开启地球毁灭器的密码.牛牛手里有一个字符串S,牛牛还记得从S中去掉一个字符就恰好是正确的密码,请你帮牛牛求出 ...
- 如何使用命令行cmd执行java程序
如果你的电脑上没有像idea eclipse这类的IDE,但是因为工作需要必须要执行java代码怎么办呢? 这个时候就需要使用电脑最原始的执行方式 既命令行 1:首先你得安装了jdk与jre (这里就 ...
- 如何让Oracle释放undo表空间
如何让Oracle释放undo表空间 最佳答案 在日常的数据库维护和数据库编程中经常会遇到犹豫对大数据量做DML操作后是得ORACLE的undo表空间扩展到十几个G或者几十个G 但是这些表空间 ...
- Ubuntu超好用软件:markdown编辑器
Ubuntu上好用的markdown编辑器:typora 安装教程: sudo add-apt-repository ppa:hzwhuang/ss-qt5 sudo apt-get update s ...
- Python优缺点
优点 简单----Python是一种代表简单主义思想的语言.阅读一个良好的Python程序就感觉像是在读英语一样,尽管这个英语的要求非常严格!Python的这种伪代码本质是它最大的优点之一.它使你能够 ...
- Boyer-Moore Majority Vote Algorithm
介绍算法之前, 我们来看一个场景, 假设您有一个未排序的列表.您想知道列表中是否存在一个数量占列表的总数一半以上的元素, 我们称这样一个列表元素为 Majority 元素.如果有这样一个元素, 求出它 ...
- java.lang.NoSuchMethodError:android.content.Context.getDrawable
今天在开发的时候,这个代码在源码中是可以看到的,但是在android 4.3手机上面会报错,具体错误信息和代码如下: setBackgroundDrawable(context.getDrawable ...
- 嵌入式GPIO接口及操作(一)
GPIO意思就是通用输入输出,一些引脚可以通过他们输出高低电平,或者通过它们读入引脚的状态.对GPIO的操作是对所有硬件的操作最基本的技能.一.通过寄存器来操作GPIO引脚,一个引脚可以用于输入.输出 ...
- centos7安装mysql(yum)
centos7安装mysql(yum) ----安装环境----依赖安装----检查mysql是否已安装----安装----验证是否添加成功----选择要启用的mysql版本----通过Yum安装my ...
- localStorage与sessionStorage区别
localStorage与sessionStorage区别:浏览器正常模式下: 关闭浏览器或该窗口标签时,localStorage数据依然保存,但是sessionStorage数据会被清除. ...