Spark RDD的fold和aggregate为什么是两个API?为什么不是一个foldLeft?

基于STM32的简易电压、频率、占空比测量仪 任务详解:我们需要实现三个功能: 第一个是测频率的功能,输入信号为频率为1kHz~10kHz的三种波形(方波、三角波、正弦波),这也是我们最常见的三种波形。幅度是不需要测量的,所以先不关心幅度。 第二个是电压报警功能,当输入信号的幅度超过15V时,我们需要报警(这里我用了一个红色LED当报警器,有条件的还可以加个蜂鸣器)并且把此时的信号幅度显示在OLED屏幕上。 第三个是通信方式的要求,需要有串口通信功能。 第四个是计算占空比的任务,这个任务的输入是幅度为1V~10V、频率为20Hz ~1kHz的方波,需要 阅读详情

欢迎关注我的新博客地址:http://cuipengfei.me/blog/2014/10/31/spark-fold-aggregate-why-not-foldleft/

大家都知道Scala标准库的List有一个用来做聚合操作的foldLeft方法。

比如我定义一个公司类:

1
case class Company(name:String, children:Seq[Company]=Nil)

它有名字和子公司。 然后定义几个公司:

1
val companies = List(Company("B"),Company("A"),Company("T"))

三家大公司,然后呢,我假设有一家超牛逼的公司把它们给合并了:

1
companies.foldLeft(Company("King"))((king,company)=>Company(name=king.name,king.children:+company))

这个执行的结果是这样的:

1
2
scala> companies.foldLeft(Company("King"))((king,company)=>Company(name=king.name,king.children:+company))
res6: Company = Company(King,List(Company(B,List()), Company(A,List()), Company(T,List())))

可见foldLeft的结果是一家包含了BAT三大家得新公司。

由List[Company]聚合出一个新的Company,这种属于foldLeft的同构聚合操作。

同时,foldLeft也可以做异构的聚合操作:

1
companies.foldLeft("")((acc,company)=>acc+company.name)

它的执行结果是这样的:

1
2
scala> companies.foldLeft("")((acc,company)=>acc+company.name)
res7: String = BAT

由List[Company]聚合出一个String。

这样的API感觉很方便,只要是聚合,无论同构异构,都可以用它来做。

最近接触了Spark,其中的RDD是做分布式计算时最常用的一个类。

RDD有一个叫做fold的API,它和foldLeft的签名很像,唯一区别是它只能做同构聚合操作。

也就是说如果你有一个RDD[X],通过fold,你只能构造出一个X。

如果我想通过一个RDD[X]构造一个Y出来呢?

那就得用aggregate这个API了,aggregate的签名是这样的:

1
aggregate[U](zeroValue: U)(seqOp: (U, T) ⇒ U, combOp: (U, U) ⇒ U)(implicit arg0: ClassTag[U]): U

它比fold和foldLeft多需要一个combOp做参数。

这让我很不解,同构和异构的API干嘛非得拆成两个呢?怎么不能学Scala的标准库,把它做成类似foldLeft的样子呢?

后来想明白了,这是由于Spark需要分布运算造成的。

先想一下Scala List的foldLeft是怎么工作的?

1
companies.foldLeft(Company("King"))((king,company)=>Company(name=king.name,king.children:+company))
  1. 拿到初始值,即名字为king的公司,把它和list中的第一个公司合并,成为一个包含一家子公司的新公司
  2. 把上一步中的新公司拿来和list中的第二个公司合并,成为一个包含两家子公司的新公司
  3. 把上一步中的新公司拿来和list中的第三个公司合并,成为一个包含三家子公司的新公司

这是同构的过程。

1
companies.foldLeft("")((acc,company)=>acc+company.name)
  1. 拿到初始值,即空字符串,把它和list中的第一个公司的名字拼在一起,成为B
  2. 把上一步中的B第二个公司名字拼一起,成为BA
  3. 把上一步中的BA拿来和list中的第三个公司的名字拼一起,成为BAT

这是异构的过程。

像多米诺骨牌一样,从左到右依次把list中的元素吸收入结果中。

现在假设RDD[X]中有一个类似foldLeft的API,其签名和foldLeft一致,我现在调用foldLeft,给它一个f:(Y,X)=>Y,接下来该发生什么呢?

  1. 因为要分布计算,所以我先要把手里的很多个X分成几份,分发到不同的节点上去
  2. 每个节点把拿到的很多个X计算出一个Y出来
  3. 把所有节点的结果拿来,这时我手里就有了很多个Y
  4. 啊。。。我不知道怎么把很多个Y变成一个Y啊。。。

由于Spark的RDD不像Scala的List一样只需要推倒一副多米诺骨牌,而是要推倒很多副,最后再对很多副多米诺骨牌的结果做聚合。

这时如果是同构还好,我只需要再用f:(X,X)=>X做一遍就ok了。

但是如果是异构的,那我就必须得再需要一个f:(Y,Y)=>Y了。

windows10系统上安装最新版mysql 8.0详细步骤 阅读详情

相关推荐

鸿蒙ijkplayer播放器调优实战:从卡顿掉帧到流畅播放RTSP,我都调了哪些参数?

本文深入解析鸿蒙平台上ijkplayer播放器优化RTSP流媒体播放的关键参数,解决卡顿、掉帧等问题。通过调整缓冲区管理、帧处理策略和网络超时设置,实现流畅播放体验,特别适用于监控和直播等高实时性场景。

weixin_29304021的博客 242

Kotlin | 高阶函数reduce()、fold()详解

reduce()适用于不需要初始值的聚合操作,fold()适用于需要初始值的聚合操作。reduce()操作可以直接返回聚合后的结果,而fold()操作需要通过lambda表达式的返回值来更新累加器的值。在使用时,需要根据具体场景来选择使用哪个函数。

小马快跑的博客 2651

显示模组Bonding IC气泡问题的诊断与优化策略

本文深入分析了显示模组Bonding IC气泡问题的成因与优化策略,涵盖IC两端剥离气泡、彩虹状水汽气泡、电极下方无规律气泡及IC输入端气泡等类型。通过工艺参数优化、材料存储处理、清洁环境控制及维修品特殊处理等多维度解决方案,有效降低气泡不良率。同时介绍了纳米改性ACF材料、激光辅助排泡技术等前沿解决方案,为触控显示行业提供实用参考。

weixin_26805597的博客 420

Scala学习笔记——reduce、fold、scan

Scala学习笔记之reduce、fold、scan 文章目录`Scala`学习笔记之`reduce`、`fold`、`scan``1. reduce化简`概念与区别:示例:`1.` 计算给定集合的元素和:`2.` 计算`n!`:`2. fold折叠`概念与区别:示例:`1.` 计算`n!`(`reduce`的优化):`2.` 统计字符串中每个字符出现的频次:`3. scan扫描`概念与区别: ...

Au的博客 3810

C8T6和ZET6选型更换过程中出现.\Obj\Project.sct(7): error: L6235E: More than one section matches selector - cann

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、问题原因二、解决方法三、现象总结 前言 又一件离谱的事情发生了,我之前转换过程中没有发生的错误,今天拿出来程序重新编译了一下,结果他奶奶滴一个新的错误出现了,而且我还完全不知道是什么原因导致的,先上图: 一、问题原因 之前我已经尝试过更换芯片选型,但是没有出现此类问题,今天更改的时候发现了,我还以为是个偶然错误,结果换来换去,还是有这个问题,那我之前说c8t6的程序更改成zet6上跑只需改芯片选型和宏定义岂不是啪啪打.

wx18045623090的博客 1490

史上最全工商银行核心系统建设历程:从“数据集中”到“ECOS”2.0,见证银行业信息科技跨时代发展征程

ECOS工程的直接成果是建成了工商银行第五代信息系统,即从单一核心银行系统到去核心化开放生态系统,率先开启了以智能化、开放化为特征,数据驱动引领经营模式变革,创新提出了一整套国际领先的分布式开放生态银行系统建设方案,在大型银行全分布式系统架构、主机下移、银行系统生态化转型、大规模交易型分布式数据库等多个领域再次实现“0到1”的突破,建成了具备国际领先水平的全分布式开放生态银行系统,继续勇立数字化转型潮头,推动高质量发展再上新台阶。工商银行的业务连续性管理水平实现了跨越式发展,有力地保障了业务发展。

银行信息系统应用架构详解 826

[Kotlin 开发] reduce和fold的区别

1.先写个小例子 reduce println((0..5).reduce { acc, i -> Log.e("reduce ====","acc:"+acc+" i:" + i) acc + i }) // 输出结果: // E/reduce ====: acc:0 i:1 // E/reduce ====: acc:1 i:2 // E/reduce ====: acc:3 i:3 // E/reduce ====: acc:6 i:4 // E/reduce ====:

u010130947的专栏 2098

YOLO系列算法改进 | C2PSA改进篇 | 融合FSD频域结构解耦模块 | 双域解耦感知,兼顾全局亮度与局部纹理,适应红外小目标与边缘部署场景 | ICME 2026

YOLO系列算法改进 | C2PSA改进篇 | 融合FSD频域结构解耦模块 | 双域解耦感知,兼顾全局亮度与局部纹理,适应红外小目标与边缘部署场景 | ICME 2026 (以YOLO26最新目标检测模型为基础,利用C2PSA_FSD创新模块进行改进)

2502_91881744的博客 316

RDD之fold()方法

RDD之fold()方法 简述: fold()和reduce()一样的,但是fold()需要提供初始值。 直接看代码: //分成2个区 JavaRDD<Integer> numRdd= sc.parallelize(Arrays.asList(1,2,3,4),2); //fold注意:计算每个分区之后还要合并分区结果,合并时也需要加上初始值 Integer fold = numRdd.fold(10, new Function2&

weixin_45264992的博客 478

**YOLOv11性能突破:基于YOLOv10-PSA注意力机制的目标检测革命性升级**

购买即可解锁300+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,别人有的本专栏也有!

m0_71589036的博客 197

redhawk:使用rh_setup.pl产生gsr模板

必须加的option工具会在rh_setup.pl给出提示,按照要求填写即可,另外工具会把所有填写的输入文件和信息放到rh_setup.init文件中,拷贝这个文件可在任何平级运行目录下,直接rh_setup.pl产生gsr以及run sta/dyn/em的脚本。rhsetup.pl -top top_cell_name -vdd_nets VDD 1.2 VDD2 1.2 -vss_nets VSS -frequency 100e6 (100m是默认值)更多学习内容请关注「拾陆楼」知识星球。

m0_61544122的博客 1055

learning-spark学习笔记(2):reduce()、fold()和aggregate()的区别

reduce()、fold()和aggregate()都是在spark中对RDD的聚合操作,在理解这几个函数的时候费了一点劲 reduce()和fold()要求操作的RDD是同种类型,也就是操作的元素类型和返回的元素类型一致 temp = sc.parallelize([1,2,3,4]) sum = temp.reduce(lambda x, y: x + y) 注意这里x指的是这...

sdoddyjm68的博客 2922

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

fold函数_Java中使用Map and Fold进行函数式编程

fold函数 在函数式编程中,Map和Fold是两个非常有用的运算符,它们属于每种函数式语言。 如果Map和Fold运算符是如此强大且必不可少,那么您如何解释说即使Java编程语言缺少这两个运算符,我们也可以使用Java来完成工作? 事实是,使用Java进行编码时,您已经进行了Map和Fold,只是每次都使用循环手动进行操作。 免责声明:我不是函数式编程的参考,本文不过是一个简短的介绍。 F...

最佳 Java 编程 934

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Spark基础知识20_Scala遍历操作,map和flatMap操作、fliter、reduce、fold

对lambda表达式含义的解释--->遍历到的元素赋值给s,然后让s去执行后续方法,这样就可以一个一个转换掉,此例中,会把值给s,然后执行.toUpperCase方法,然后再遍历,再执行下去.朗母达表达式,匿名函数case模式匹配,kv._1表示匹配的键,kv._2表示的匹配的值,这是元组的表达方式,这些遍历方法都可以去尝试。10 作为初始的s ,10 * 1,10 * 2, 20 * 3 ,60 * 4,240 *5。这些元素就构成了很大的集合,得到非常多的元素构成的整体的集合,就是我们所要的结果。

Matrix70的博客 1684

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Spark编程之基本的RDD算子之fold,foldByKey,treeAggregate, treeReduce

Spark编程之基本的RDD算子之fold,foldByKey,treeAggregate, treeReduce 1) fold def fold(zeroValue: T)(op: (T, T) => T): T这个api算子接收一个初始值,fold算子传入一个函数,合并两个同类型的值,同时返回一个相同类型的值这个算子在每个分区对值进行合并。在每个分区合并时以一个zeroValue作为在每个在每

stevekangpei的博客 818

Scala中,reduce, fold, 和 sorted

: 这个函数主要用于将集合中的元素通过某种累积规则(比如加法、乘法、最大值查找等)组合成单个结果。它从左到右遍历集合,并应用给定的二元操作函数(如。:这个函数用于返回一个排序后的集合副本,原集合不会改变。对于List,SortedSet或SortedMap,,但是从右到左遍历集合。这个在某些上下文中可能会更自然,尤其是当操作需要在每个元素上依赖之前的结果时。直接按元素自然顺序排序;而对于自定义类型的序列,需要提供一个比较器(Comparator)。

2401_82366115的博客 525

Spark核心之aggregate和fold

在本文中介绍Spark中Action的两种算子,分别是aggregate和fold,其方法定义分别为: • aggregate[U](zeroValue: U)(seqOp: (U, T) => U, combOp: (U, U) => U)(implicit argO: ClassTag[U]): U • fold(zero Value: T)(op: (T, T) =...

LMR的博客 9625

函数式编程里面的fold

第一:基本概念 fold在函数式编程里面的基本含义是遍历数据结构,最后产生一个聚合值。最简单的例子是sum list = foldl (+) 0 list fold抽象了两个动作,一个是遍历数据结构本身,一个是累积值和元素之间的关系。用了fold后就只需要关心聚合的初始值是什么,每个元素和累积值如何产生下一个累积值。 比如上面的sum的例子,初始值是0, 步进函数式+, 也就是每个元

在理想和现实之间来回碰撞的程序员 4897

Kotlin 中 fold 和 reduce 的基本区别是什么

在 Kotlin 中都是强大的聚合操作函数,但在使用时需要根据具体情况选择合适的函数。如果需要一个初始值来确保结果的类型或者处理空集合的情况,在这个例子中,初始值为 0,每次迭代将累加器和列表中的元素相加,最终得到列表元素的总和。同样对于计算整数列表中所有元素的总和,如果确定列表不为空,可以使用。这里直接对列表中的两个元素进行操作,逐步将结果累加到最终的总和。假设我们有一个整数列表,想要计算列表中所有元素的总和,可以使用。如果集合不为空且不需要初始值,在 Kotlin 中,可以提供更简洁的语法。

challenge51all的专栏 822

fold函数和reduce函数的区别(不特指spark)

In a fold over a collection, the accumulator type may be different than the type of the collection, and a zero element is usually given. In a reduce, you don't give a zero element and the accumulato

点火三周的专栏 4122

scala练习——fold函数

题目 用fold方法将数组中的每个列表相同下标的元素进行聚合。 数据:Array(List(2,3,4), List(1,2,3), List(4,5,6)) 结果为:Array(7,10,13) 解析 fold函数,英文翻译意为折叠,其源代码如下: def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op) //该函数有两个参数,且后一个参数为一个函数,两个参数是采用柯里化联合到一起的。后面调回的是 //foldL

yeah_you_are的博客 897

Spark算子[11]:reduce、aggregate、fold 详解

以上三个方法操作都是对RDD进行的聚合操作。1、reduce()与fold()方法是对同种元素类型数据的RDD进行操作,即必须同构。其返回值返回一个同样类型的新元素。val nums = Array(1,2,3,4,5,6,7,8,9) val numsRdd = sc.parallelize(nums,3) val reduce = numsRdd.reduce((a,b) => a+b)2、fo

行走的树 3108

Scala高阶函数之 map, reduce, flatMap(扁平化), fold(折叠), scan(扫描)

高阶函数: 高阶函数是指使用其他函数作为参数、或者返回一个函数作为结果的函数。在Scala中函数是“一等公民”,所以允许定义高阶函数。这里的术语可能有点让人困惑,我们约定,使用函数值作为参数,或者返回值为函数值的“函数”和“方法”,均称之为“高阶函数”。 最常见的一个例子是Scala集合类(collections)的高阶函数map object HighOrderFunDemo02 { def...

李昊轩的博客 1965

fold函数如何使用与如何用fold函数求最小值

【代码】fold函数如何使用与如何用fold函数求最小值。

CYLktiao的博客 211
上一篇: Scala中Stream的应用场景及其实现原理
下一篇: 15篇干货博客 38本书 4门公开课 减掉20斤体重 我的2014总结
崔鹏飞
博客等级 码龄19年 441粉丝 128原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值