RDD(五)——action
reduce(func)
通过func函数聚集RDD中的所有元素并得到最终的结果,先聚合分区内数据,再聚合分区间数据。Func函数决定了聚合的方式。
def main(args: Array[String]): Unit = {
val sc: SparkContext = new SparkContext(new SparkConf().
setMaster("local[*]").setAppName("spark"))
val value: RDD[Int] = sc.makeRDD(Array(1,2,3))
val result: Int = value.reduce(_ + _)
println(result)
val value1: RDD[(String, Int)] = sc.makeRDD(Array(("a", 1), ("b", 2), ("c", 3)))
val tuple: (String, Int) = value1.reduce((x: (String, Int), y: (String, Int)) => (x._1 + y._1, x._2 + y._2))
println(tuple)
}
打印结果为:
6
cba 6
collect()案例
在驱动程序中,以数组的形式返回数据集的所有元素。数组的元素类型为RDD的元素类型;
count()案例
返回RDD中元素的个数
val value: RDD[Int] = sc.makeRDD(Array(1,2,3))
println(value.count())
first()、take()
first返回RDD中的第一个元素
take返回一个由RDD的前n个元素组成的数组
从first的原码来看,它底层是由take实现的;
def first(): T = withScope {
take(1) match {
case Array(t) => t
case _ => throw new UnsupportedOperationException("empty collection")
}
}
查看take的原码及其注释,原码目前看不大懂,应该是去取出相应个数的分区,将分区中的元素装配成数组,再返回该数组。所以可以这么理解:first取出的是第一个分区的第一个元素,take取出的是前x个分区的n个元素;
/**
* Take the first num elements of the RDD. It works by first scanning one partition, and use the
* results from that partition to estimate the number of additional partitions needed to satisfy
* the limit.
*
* @note This method should only be used if the resulting array is expected to be small, as
* all the data is loaded into the driver's memory.
*
* @note Due to complications in the internal implementation, this method will raise
* an exception if called on an RDD of `Nothing` or `Null`.
*/
def take(num: Int): Array[T] = withScope {
...
}
示例代码如下:
def main(args: Array[String]): Unit = {
val sc: SparkContext = new SparkContext(new SparkConf().
setMaster("local[*]").setAppName("spark"))
val value: RDD[Int] = sc.makeRDD(Array(3,6,4,5,8,1,2,0),4);
value.saveAsTextFile("E:/idea/spark2/out/take")
println(value.first())
value.take(3).foreach(println)
}
数据在分区的分布如下:
36 45 81 20
first取出的元素是3;
take取出的元素是364
印证了上述的函数执行逻辑;
takeOrdered(n)
返回该RDD排序(升序)后的前n个元素组成的数组
aggregate
参数:(zeroValue: U)(seqOp: (U, T) ⇒ U, combOp: (U, U) ⇒ U)
作用:aggregate函数将每个分区里面的元素通过seqOp和初始值进行聚合,然后用combine函数将每个分区的结果和初始值(zeroValue)进行combine操作。这个函数最终返回的类型不需要和RDD中元素类型一致。(分区内要与初始值进行聚合操作,分区间也要与初始值进行聚合操作)与reduce算子相比,aggregate能分别控制分区间和分区内的运算。
def main(args: Array[String]): Unit = {
val sc: SparkContext = new SparkContext(new SparkConf().
setMaster("local[*]").setAppName("spark"))
val value: RDD[Int] = sc.makeRDD(Array(1, 2, 3, 4), 4)
val i: Int = value.aggregate(0)(_ + _, _ + _)//它这里的函数类型是可以推断出来的
println(i)
}
打印结果为10;
fold(num)(func)
折叠操作,aggregate的简化操作,seqop和combop一样。
countByKey()
针对(K,V)类型的RDD,返回一个(K,Int)的map,表示每一个key对应的元素个数。
def main(args: Array[String]): Unit = {
val sc: SparkContext = new SparkContext(new SparkConf().
setMaster("local[*]").setAppName("spark"))
val value: RDD[(String, Int)] = sc.parallelize(Array(("a", 3), ("a", 2),("b",1)))
val result: collection.Map[String, Long] = value.countByKey()
result.foreach(println)
}
打印结果为:
(a,2)
(b,1)
foreach(func)
在数据集的每一个元素上,运行函数func进行更新。
def main(args: Array[String]): Unit = {
val sc: SparkContext = new SparkContext(new SparkConf().
setMaster("local[*]").setAppName("spark"))
val raw: RDD[Int] = sc.makeRDD(Array(1, 2, 3, 4), 4);//driver端执行
val ints: Array[Int] = raw.collect()
ints.foreach(x => {println(x+1)})//在driver端执行
raw.foreach(x => {println(x+1)})//在executor端执行
}
}
foreachPartition()
在数据集的每一个分区上,运行函数func()进行更新。它与foreach的源码如下:
/**
* Applies a function f to all elements of this RDD.
*/
def foreach(f: T => Unit): Unit = withScope {
val cleanF = sc.clean(f)
sc.runJob(this, (iter: Iterator[T]) => iter.foreach(cleanF))
} /**
* Applies a function f to each partition of this RDD.
*/
def foreachPartition(f: Iterator[T] => Unit): Unit = withScope {
val cleanF = sc.clean(f)
sc.runJob(this, (iter: Iterator[T]) => cleanF(iter))
}
他们之间的性能区别类似于map与mapPartition。更详细的例子见博客《JdbcRDD连接MySQL》
RDD(五)——action的更多相关文章
- 关于spark RDD trans action算子、lineage、宽窄依赖详解
这篇文章想从spark当初设计时为何提出RDD概念,相对于hadoop,RDD真的能给spark带来何等优势.之前本想开篇是想总体介绍spark,以及环境搭建过程,但个人感觉RDD更为重要 铺垫 在h ...
- Spark RDD概念学习系列之Pair RDD的action操作
不多说,直接上干货! Pair RDD的action操作 所有基础RDD 支持的行动操作也都在pair RDD 上可用
- spark transform操作卡死,请先对rdd进行action操作
这两天一直在写spark程序,遇到了一个奇怪的问题. 问题简单描述如下,有两个RDD,设为rdd_a,rdd_b,当将这两个rdd合并的时候,spark会在运行中卡死. 解决方式也是奇葩. 只要在合并 ...
- Struts(五)Action的访问
在struts开发中,Action作为框架的核心类,实现对用户的请求的处理,Action被称为业务逻辑控制器.一个Action类代表一次请求或调用.Action就是用来处理一次用户请求的对象 Acti ...
- Struts2(五)Action二配置
一.method参数 action package com.pb.web.action; public class HourseAction { public String add(){ System ...
- vuex 源码分析(五) action 详解
action类似于mutation,不同的是Action提交的是mutation,而不是直接变更状态,而且action里可以包含任意异步操作,每个mutation的参数1是一个对象,可以包含如下六个属 ...
- PLAY2.6-SCALA(五) Action的组合、范围的设置以及错误的处理
一.自定义action 从一个日志装饰器的例子开始 1.在invokeBlock方法中实现 import play.api.mvc._ class LoggingAction @Inject() (p ...
- 五 Action访问方法,method配置,通配符(常用),动态
1 通过method配置(有点low) 建立前端JSP:demo4.jsp <%@ page language="java" contentType="text/h ...
- Struts2学习笔记(五)——Action访问Servlet API
在Strut2中访问Servlet API有三种方式: 1.通过ActionContext访问Servlet API,推荐使用这种,但是这种方案它获取的不是真正的事Servlet API. 步骤: 1 ...
随机推荐
- BZOJ:2815: [ZJOI2012]灾难
题解: 构造灭绝树: x指向的点表示x的祖先死亡则x死亡 动态LCA: 可以用LCT维护或直接更新倍增数组 最后统计子树点的个数 坑: 我还不会序列型Toposort #include<iost ...
- TP多条件查询实例
where条件查询,时间范围查询 $condition = [ ['member_id', '=', $member_id] ]; if($type) { $condition[] = ['type' ...
- 了解OOM
1)什么是OOM? OOM,全称“Out Of Memory”,翻译成中文就是“内存用完了”,来源于java.lang.OutOfMemoryError.看下关于的官方说明: Thrown when ...
- JavaScript—纯函数
定义 一个函数的返回结果只依赖它的参数,而且在计算过程中不会产生其他副作用,也就是不会对外部的数据造成影响或改变. 理解:函数的返回结果只依赖它的参数 const a= 1; const b= (c) ...
- sql优化从300秒到7秒
原始sql select b.jd 街道,b.rglm 楼宇,zzrl 楼宇编号,count(oname) 入楼企业总数, (select count(oname) from ${tablename} ...
- == 与 equals区别(HashCode方法)
1:==分析 1.2:基本类型比较 判断基本类型的数值是不是相等 1.3:对象类型比较 判断两个引用是不是指向同一个对象,即内存地址是不是相等. 2:equals分析 来判断对象内容是不是相等,一般有 ...
- VUE 引用公共样式
首先创建公共样式文件 在main.js中引用样式 浏览器效果图
- C/C++源程序到可执行程序的过程
源程序.cpp 预处理得到 预处理文件.i 编译得到 汇编文件.S 汇编得到 目标文件.o 链接得到 可执行文件 例子:main.cpp fun.cpp fun.h #inclu ...
- pip速度慢解决办法
pip速度慢解决办法 sudo pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 注意加不加sudo是 ...
- Physicoochemical|CG content|
NCBI存在的问题: 数据用户的增长 软件开发受限 数据分析缺乏 有些传统束缚,仅用底层语言书写 Pangenome Open gene是随菌株数量增大而增大的gene,Closed gene是随菌株 ...