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的更多相关文章

  1. 关于spark RDD trans action算子、lineage、宽窄依赖详解

    这篇文章想从spark当初设计时为何提出RDD概念,相对于hadoop,RDD真的能给spark带来何等优势.之前本想开篇是想总体介绍spark,以及环境搭建过程,但个人感觉RDD更为重要 铺垫 在h ...

  2. Spark RDD概念学习系列之Pair RDD的action操作

    不多说,直接上干货! Pair RDD的action操作 所有基础RDD 支持的行动操作也都在pair RDD 上可用

  3. spark transform操作卡死,请先对rdd进行action操作

    这两天一直在写spark程序,遇到了一个奇怪的问题. 问题简单描述如下,有两个RDD,设为rdd_a,rdd_b,当将这两个rdd合并的时候,spark会在运行中卡死. 解决方式也是奇葩. 只要在合并 ...

  4. Struts(五)Action的访问

    在struts开发中,Action作为框架的核心类,实现对用户的请求的处理,Action被称为业务逻辑控制器.一个Action类代表一次请求或调用.Action就是用来处理一次用户请求的对象 Acti ...

  5. Struts2(五)Action二配置

    一.method参数 action package com.pb.web.action; public class HourseAction { public String add(){ System ...

  6. vuex 源码分析(五) action 详解

    action类似于mutation,不同的是Action提交的是mutation,而不是直接变更状态,而且action里可以包含任意异步操作,每个mutation的参数1是一个对象,可以包含如下六个属 ...

  7. PLAY2.6-SCALA(五) Action的组合、范围的设置以及错误的处理

    一.自定义action 从一个日志装饰器的例子开始 1.在invokeBlock方法中实现 import play.api.mvc._ class LoggingAction @Inject() (p ...

  8. 五 Action访问方法,method配置,通配符(常用),动态

    1 通过method配置(有点low) 建立前端JSP:demo4.jsp <%@ page language="java" contentType="text/h ...

  9. Struts2学习笔记(五)——Action访问Servlet API

    在Strut2中访问Servlet API有三种方式: 1.通过ActionContext访问Servlet API,推荐使用这种,但是这种方案它获取的不是真正的事Servlet API. 步骤: 1 ...

随机推荐

  1. BZOJ:2190: [SDOI2008]仪仗队

    题解:欧拉函数 #include<iostream> #include<cstdio> #include<cstring> using namespace std; ...

  2. expresscache和primocache加速资料整理-centos7缓存加速

    expresscache和primocachehttp://www.360doc.com/content/16/0111/17/256680_527142090.shtml 安装expresscach ...

  3. 关于torch.nn.Linear的笔记

    关于该类: torch.nn.Linear(in_features, out_features, bias=True) 可以对输入数据进行线性变换: $y  = x A^T + b$ in_featu ...

  4. 201903-1 小中大 Java

    思路: 中位数就是排序后中间的那个数.如果有偶数个数,就是中间两个数的平均值. 注意,这个平均值可能是整数,可能是小数,如果都是一样的处理,如果输出整数是3.0,而不是3,就有问题.所以需要分开处理. ...

  5. PAT Advanced 1034 Head of a Gang (30) [图的遍历,BFS,DFS,并查集]

    题目 One way that the police finds the head of a gang is to check people's phone calls. If there is a ...

  6. Tensorflow学习教程------变量

    #coding:utf-8 import tensorflow as tf x = tf.Variable([1,2]) a = tf.constant([3,3]) #增加一个减法op sub = ...

  7. pytorch安装及基本用法

    20180425更新  安装pytorch0.4.0: conda uninstall pytorch # 如果是CUDA版本的话 conda uninstall cuda80 cuda90 # 如果 ...

  8. 81.常用的返回QuerySet对象的方法使用详解:values和values_list

    values: 指定提取的数据库表中的字段值,如果不指定任何的字段名的话,默认情况下会提取所有的字段值.但是需要注意的是使用values返回的QuerySet对象中包括的是一个个的字典. 1.提取与A ...

  9. Windows 远程桌面连接 CentOS7 (xrdp)

    Windows 远程桌面连接 CentOS7 (xrdp) 前提: CentOS安装桌面,如果无桌面,请执行: yum -y groups install "GNOME Desktop&qu ...

  10. 吴裕雄--天生自然MySQL学习笔记:MySQL 数据类型

    MySQL中定义数据字段的类型对你数据库的优化是非常重要的. MySQL支持多种类型,大致可以分为三类:数值.日期/时间和字符串(字符)类型. 数值类型 MySQL支持所有标准SQL数值数据类型. 这 ...