spark 基于分区操作 mapPartitions

Spark分区方式详解 一、Spark数据分区方式简要              在Spark中,RDD(Resilient Distributed Dataset)是其最基本的抽象数据集,其中每个RDD是由若干个Partition组成。在Job运行期间,参与运算的Partition数据分布在多台机器的内存当中。这里可将RDD看成一个非常大的数组,其中Partition是数组中的每个元素,并且这些元素分布在多台机器中。... 阅读详情


基于分区对数据进行操作可以让我们避免为每个数据元素进行重复的配置工作。诸如打开数据库连接或者创建随机生成数等操作,都是我们应当避免的为每个元素都配置一遍的工作。Spark提供基于分区的map和foreach,让你的部分代码只对RDD的每个分区运行一次,这样可以帮助降低这些操作的代价。

当基于分区操作RDD时,Spark会为函数提供该分区中的元素的迭代器。返回值方面,也返回一个迭代器。

Spark 提供的基于分区操作的操作符,大概有:

mapPartitions()

mapPartitionsWithIndex()

foreachPartitions()

注意:foreachPartition 和 mapPartitions的分别,foreachPartition应该属于action运算操作,而mapPartitions是在Transformation中,所以是转化操作,此外在应用场景上区别是mapPartitions可以获取返回值,继续在返回RDD上做其他的操作,而foreachPartition因为没有返回值并且是action操作,所以使用它一般都是在程序末尾比如说要落地数据到存储系统中如mysql,es,或者hbase中,可以用它。当然在Transformation中也可以落地数据,但是它必须依赖action操作来触发它,因为Transformation操作是延迟执行的,如果没有任何action方法来触发,那么Transformation操作是不会被执行的,这一点需要注意。

下面分别举几个例子:

mapPartitionsWithIndex(), 和 mapPartitions() 类似,但是同时提供分区的索引

Demo

显示每个分区元素的分区索引
scala> val rdd1 =  sc.parallelize( List("yellow","red", "blue", "cyan", "black"), 3 )
rdd1: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[101] at parallelize at <console>:26
scala> val mapped =   
     | rdd1.mapPartitionsWithIndex{
     | (index, iterator) => {
     |  println("Called in Partition -> " + index)
     | val myList = iterator.toList
     | myList.map(x => x + " -> " + index).iterator
     | }
     | }
mapped: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[102] at mapPartitionsWithIndex at <console>:29

scala> mapped.collect()
Called in Partition -> 0
Called in Partition -> 1
Called in Partition -> 2
res48: Array[String] = Array(yellow -> 0, red -> 1, blue -> 1, cyan -> 2, black -> 2)

mapPartitions():

与map方法类似,map是对rdd中的每一个元素进行操作,而mapPartitions(foreachPartition)则是对rdd中的每个分区的迭代器进行操作。

SparkSql或DataFrame默认会对程序进行mapPartition的优化。

Demo

实现将每个数字变成原来的2倍的功能

比如:输入2,结果(2,4)

使用map

scala> val a = sc.parallelize(1 to 9, 3)
a: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[103] at parallelize at <console>:26

scala> def mapDoubleFunc(a : Int) : (Int,Int) = {
     |     (a,a*2)
     | }
mapDoubleFunc: (a: Int)(Int, Int)

scala> val mapResult = a.map(mapDoubleFunc)
mapResult: org.apache.spark.rdd.RDD[(Int, Int)] = MapPartitionsRDD[104] at map at <console>:30

scala> println(mapResult.collect().mkString)
(1,2)(2,4)(3,6)(4,8)(5,10)(6,12)(7,14)(8,16)(9,18)

使用mapPartitions


scala> val a = sc.parallelize(1 to 9, 3)
a: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[105] at parallelize at <console>:26

scala> def doubleFunc(iter: Iterator[Int]) : Iterator[(Int,Int)] = {
     |     var res = List[(Int,Int)]()
     |     while (iter.hasNext)
     |     {
     |       val cur = iter.next;
     |       res .::= (cur,cur*2)
     |     }
     |     res.iterator
     |   }
doubleFunc: (iter: Iterator[Int])Iterator[(Int, Int)]

scala> val result = a.mapPartitions(doubleFunc)
result: org.apache.spark.rdd.RDD[(Int, Int)] = MapPartitionsRDD[106] at mapPartitions at <console>:30

scala> println(result.collect().mkString)
(3,6)(2,4)(1,2)(6,12)(5,10)(4,8)(9,18)(8,16)(7,14)

再举一个例子:

Demo

求平均值

不使用mapPartitions()求平均值

import org.apache.spark.rdd.RDD
val nums=sc.parallelize(List(1,2,3,4),3)

//不使用mapPartitions()求平均值
def reduce(x:(Int,Int),y:(Int,Int)):(Int,Int)={(x._1+y._1,x._2+y._2)}

def basicAvg(nums:RDD[Int]):Float={
  val sum = nums.map(x=>(x,1)).reduce(reduce)
  return sum._1 / sum._2.asInstanceOf[Float]
}

结果:

scala> basicAvg(nums)
res90: Float = 2.5

使用mapPartitions()求平均值

//使用mapPartitions()求平均值
def meanFunc(iter: Iterator[Int]) : Iterator[(Int,Int)]= {
     var x = 0
     var y = 0
     var res = List[(Int,Int)]()
     while (iter.hasNext)
     {
     val cur = iter.next
     x = x+cur
     y = y+ 1 
     }
     res .::= (x,y)
     res.iterator
}

//计算平均值
//如果没有import RDD,则需使用 org.apache.spark.rdd.RDD[Int]
def fastAvg(nums:RDD[Int]):Float={
	val sumCount = nums.mapPartitions(meanFunc).reduce(reduce)
  return sumCount._1 / sumCount._2.asInstanceOf[Float]
}

结果:

scala> fastAvg(nums)
res91: Float = 2.5

最后,需要注意一点,如果操作是iterator类型,我们是不能在循环外打印这个iterator的size,一旦执行size方法,相当于iterato就会被执行,所以后续的foreach你会发现是空值的,切记iterator迭代器只能被执行一次。




参考资料:

https://blog.youkuaiyun.com/u010454030/article/details/78897150

https://blog.youkuaiyun.com/wusuopubupt/article/details/53258067

https://blog.youkuaiyun.com/lsshlsw/article/details/48627737






Spark中mapPartitions算子详解介绍 上一节我们讲到如何使用map算子对RDD中的数据进行映射处理,但是map函数有个缺点就是不能够批处理,他是每次只处理一个元素,而本节使用的 `mapPartitions` 进行的类似于批处理,每次处理整个分区的数据。 阅读详情

相关推荐

第45课 Spark 2.0实战之Dataset:map、flatMap、mapPartitions、dropDuplicate、coalesce、repartition等

第45课 Spark 2.0实战之Dataset:map、flatMap、mapPartitions、dropDuplicate、coalesce、repartition等   package com.dt.spark200 import org.apache.spark.sql.SparkSession import scala.collection.mutable.ArrayBuffe

大模型与Agent智能体 1万+

Spark中mapPartitions使用

Spark中mapPartitions使用

Kverson 2385

ANSYS WB 网格划分详解与技巧

本文详细介绍了网格操作中的关键设置与功能选项。主要内容包括:1)网格显示风格与物理偏好设置;2)单元阶次选择对精度的影响;3)单元尺寸控制方法;4)尺寸调整功能,重点讲解了自适应尺寸调整、增长率控制和捕获曲率等选项;5)网格质量评估标准;6)四种主要划分方法(四面体、六面体主导、扫掠、多区域)的特点与适用场景;7)三种尺寸调整方式(直接调整、边缘尺寸调整、影响范围调整)的具体应用。文章强调在实际建模中需要根据模型特点合理选择网格参数,平衡计算精度与效率。

2403_87939837的博客 1698

Spark算子--map和mapPartition的区别,配实例讲解

map和mapParttion都是spark的算子,他们在进行数据处理时有一定的区别: map是RDD中的每一个元素进行操作。 mapPartition是对RDD的每一个分区的迭代器进行操作,返回的是迭代器。 mapPartiton的优势: 提高性能,比如我们对一个含有100条log数据的分区进行操作,使用map的话函数要执行100次计算。使用MapPartitions操作之后,一个task...

SOARING 1万+

JS逆向-快手__NS_hxfalcon参数分析

现在快手H5接口都需要__NS_hxfalcon这个参数,这篇文章就是逆向这个参数

ckcookies的博客 4076

IT资产管理(三)之GLPI资产录入

glpi 在 10 版本之后已经有自带的 glpi-agent 代理程序可自动获取服务器、电脑等的信息并进行自动录入和更新,不再依赖 10 版本之前的 fusioninventory 插件或者第三方资产统计平台 OCS Inventory 等

予挚之的博客 2990

spark RDD算子(十二)之RDD 分区操作上mapPartitions, mapPartitionsWithIndex

一、mapPartitions mapPartition可以倒过来理解。先partition,再把每个partition进行map函数 适用场景: 如果再映射的过程中需要频繁创建额外的对象,使用mapPartitions要比map高效的多 比如,将RDD中的所有数据通过JDBC连接写入数据库,如果使用map函数,可能要为每一个元素都创建一个connection,这样开销很大,如果使用mapPartitions,那么只需要针对每一个分区建立一个connection。 案例:把每一个元素平方 Java版本 pu

qianchun22的博客 661

Maven的下载安装配置教程(详细图文)

目录 一、简单了解一下什么是Maven 二、maven的下载 三、maven的安装 四、maven的环境变量配置 五、setting文件配置 六、开发工具配置Maven 一、简单了解一下什么是Maven Maven就是一款帮助程序员构建项目的工具,我们只需要告诉Maven需要哪些Jar 包,它会帮助我们下载所有的Jar,极大提升开发效率。 1.Maven翻译为“专家“, ”内行”的意思,是著名Apache公司下基于Java开发的开源项目。 2.Maven项目对象模型(POM)是一..

bakelFF的博客 12万+

Spark RDD算子(十一) RDD 分区操作 mapPartitions、mapPartitionsWithIndex、glom

一、mapPartitions mapPartition可以倒过来理解,先partition,再把每个partition进行map函数 适用场景 如果在映射的过程中需要频繁创建额外的对象,使用mapPartitions要比map高效。 比如,将RDD中的所有数据通过JDBC连接写入数据库,如果使用map函数,可能要为每一个元素都创建一个connection,这样开销很大,如果使用mapPartitions,那么只需要针对每一个分区建立一个connection。 下面的例子 java实现,把每一个元素平方 S

timicai的博客 378

TensorRT - 使用自定义层扩展 TensorRT

TensorRT 支持通过自定义插件扩展功能。开发者可以基于 IPluginV3 接口实现插件类,并通过 IPluginCreatorV3One 创建器类注册到 TensorRT 插件注册表。插件实现需要包含核心、构建和运行时三种能力,并通过静态或动态方式注册。最后可使用 addPluginV3() 将插件实例添加到 TensorRT 网络中。这种方法允许在标准层不满足需求时,使用自定义层扩展模型功能。

1148

黑猫带你学eMMC协议第14篇:eMMC FFU详解(Field Firmware Update)

1 前言 1.1 声明 本文依据eMMC JEDEC5.1及个人工作经验整理而成,如有错误请留言。 本文结合eMMC JEDEC5.1协议手册查看效果更佳。 1.2 内容提要 1、ffu相关寄存器有哪些? 2、如何设置ffu? 3、什么是ffu?是否能够更新旧版本的固件到emmc? 4、ffu配置流程图。 2 什么是FFU 主机下载新的固件到eMMC,下载成功后eMMC将固件安装到设备。 3 相关寄存器/命令 SUPPORTED_MODES [493] FFU_FEATURES [492] 该

黑猫奥利奥的博客 4659

大数据——Spark RDD算子(十二)RDD分区操作mapPartitions、mapPartitionsWithIndex

Spark RDD算子(十二)RDD分区操作mapPartitions、mapPartitionsWithIndexmapPartitions把每一个元素变成map(i,i*i)Scala版本Java版本把(i,j) 变成(i,j*j)Scala版本Java版本把每一个元素平方Java版本mapPartitionsWithIndex统计各个分区中的元素Scala版本Java版本 mapPartitions mapPartitions可以倒过来理解,先partition,再把每个partition进行map

蜂蜜柚子加苦茶 646

Pytorch入门实战(2)-使用BP神经网络实现MNIST手写数字识别

上一篇:Pytorch入门实战(1) - 实现线性回归 涉及知识点 Pytorch nn.Module的基本使用 Pytorch nn.Linear的基本用法 PytorchVision Transforms的基本使用 Pytorch中DataLoader的基本用法 Pytorch详解NLLLoss和CrossEntropyLoss 如何确定神经网络的层数和隐藏层神经元数量 本文内容 本文将会使用BP神经网络(就是最普通的神经网络)实现一个MNIST手写数据集的实现。话不多说,直接开始。 首先先导入需要的包

iioSnail的博客 6617

Spark RDD算子:分区操作,mapPartitions和mapPartitionsWIthIndex

mapPartitions mapPartitions的执行过程是先进行分区,然后对分区内的元素进行相应的操作。如果在映射的过程中需要频繁的创建额外的对象,使用mapPartitions比map要更加高效。 举一些例子:计算每个元素乘以2. Java端 package Action; import org.apache.spark.SparkConf; import org.apache.spark.api.java.JavaPairRDD; import org.apache.spark.api.jav

qq_43012693的博客 979

【教程4>第6章>第3节】LS信道估计与均衡系统MATLAB仿真实现

1]姬国伟,葛利嘉,龙秀虹.基于LS信道估计的SC-FDE系统性能研究[J].军事通信技术, 2010(1):6.DOI:CNKI:SUN:JSTY.0.2010-01-013.在无线通信中,信号在空间传播时,随着传输距离增加,能量会逐渐扩散,导致信号幅度减小,即发生衰减。第四个图表示的是提取的信道估计值,可以看到,在不插值的前提下,得到的信道估计值基本接近真实的信道h。从第五个图可知,通过信道估计,对接收信号进行了校正和补偿。信道模型,先通过awgn加入噪声,然后乘以hreal,模拟通过信道。

FPGA/MATLAB学习教程/源码/项目合作开发 389

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Spark RDD算子之RDD 分区操作 -- mapPartitions、mapPartitionsWithIndex、glom

1、mapPartitions 先 partition,再把每个 partition 进行 map 函数 适用场景 如果在映射的过程中需要频繁创建额外的对象,使用mapPartitions要比map高效的多。 比如,将RDD中的所有数据通过JDBC连接写入数据库,如果使用map函数,可能要为每一个元素都创建一个connection,这样开销很大,如果使用mapPartitions,那么只需要针对每一个分区建立一个connection。 把 RDD 中每一个元素平方! Java版本 SparkConf con

绿萝蔓蔓绕枝生 629

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Spark RDD算子只分区操作mapPartitions、mapPartitionsWithIndex(scala和java版本)

mapPartitions 可以理解为先进行partition,再对每一个partition进行map 1、把每一个元素 i 变为 map(i , i*i) scala版本 val rdd = sc.parallelize(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) def mapPartFunc(iter: Iterator[Int]): Iterator[(Int, Int)] = { val res = List[(Int, Int)]()

xiaoxionghanhan的博客 563

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

spark labeledpoint函数用法_Spark性能优化:基于分区进行操作

我的原创地址:Spark性能优化:基于分区进行操作​dongkelun.com前言(摘自Spark快速大数据分析)基于分区对数据进行操作可以让我们避免为每个数据元素进行重复的配置工作。诸如打开数据库连接或创建随机数生成器等操作,都是我们应当尽量避免为每个元素都配置一次的工作。Spark 提供基于分区的map 和foreach,让你的部分代码只对RDD 的每个分区运行一次,这样可以帮助降低这些操作的...

weixin_39636718的博客 378

Spark核心编程3-map,mapPartitions,flatMap,glom,分区,groupby

一、算子介绍(RDD方法既称为算子) RDD方法分为转换和行动两个内容。 转换:功能的补充,也就是复杂业务逻辑,生产多个RDD的过程,旧的RDD包装成新的RDD,相互包装补充; 行动:触发任务调度和作业的执行。封装并不会触发任务的执行,如flatmap,map等,只有collect等才能触发。 二、转换算子(RDD方法) 根据数据类型不同可以把算法分为三大类型单value ,双value,key-value; 2.1 map map函数式将处理的数据逐条进行映射转换,可以是值或者类型的转换。.

Icedeny的博客 723

spark map和mapPartitions区别

主要区别: map是对rdd中的每一个元素进行操作; mapPartitions则是对rdd中的每个分区的迭代器进行操作 MapPartitions的优点: 如果是普通的map,比如一个partition中有1万条数据。ok,那么你的function要执行和计算1万次。 使用MapPartitions操作之后,一个task仅仅会执行一次function,function一次接收所有...

weixin_36058293的博客 307

Spark部分:按照分区插入数据(map,mappartitions和foreachPartition)【Java版全代码】

package com.bjsxt.spark; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.apache.spark.api.java.function.Function; import org.apache...

wyqwilliam的博客 3197

spark中分区算子

功能:对RDD每个分区的数据进行操作,将每个分区的数据进行map转换,将转换的结果放入新的RDD中。

qq_58242165的博客 267

Spark使用mapPartitions获取分区下的元素

mapPartitions解析 底层源码 /** * Return a new RDD by applying a function to each partition of this RDD. * * `preservesPartitioning` indicates whether the input function preserves the partitioner,...

Jamie's Blogs 714

RDD转换操作算子 --- map类

转换操作RDD算子 map 将RDD一对一的转化为另一种形式 @Test def map(): Unit ={ //val source: Seq[Int] = Seq(1,2,3,4,5,6) val source: RDD[Int] = sc.parallelize(Seq(1,2,3,4,5,6)) val map: Array[Int] = source.map(item => item*10) .collect() map.forea

懂得一千零一种,赋予你失败的方法! 1488

2.3.1.2 Value类型-mapPartitions()以分区为单位执行Map

2.3.1.2 Value类型-mapPartitions()以分区为单位执行Map ----------------转载放原连接,违权必究-------------------------- 1、格式: mapPartitions(f : Iterator[T]=> Iterator[U],pP:Boolean = false) : RDD[U] 2、功能: 1、原来RDD中的元素按照一个分区为一个Iterator,遍历分区 2、每个分区数据(Iterator)依次按批次进入mapPartitio

qq_41549462的博客 237
上一篇: 动手实现第一个Hadoop程序的扩展
下一篇: 一个简单的UDF小程序(HIVE)
ITrue的天空
博客等级 码龄14年 4粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值