mapGroups 是 Spark 中一个强大的分组操作函数,它允许你对每个分组应用自定义逻辑并返回一个结果。以下是多个使用简单样例数据的具体用法示例。

基础示例数据

假设我们有一个简单的学生成绩数据集:

// 创建示例DataFrame
val studentScores = Seq(("Math", "Alice", 85),("Math", "Bob", 92),("Math", "Charlie", 78),("Science", "Alice", 88),("Science", "Bob", 95),("Science", "Charlie", 82),("English", "Alice", 90),("English", "Bob", 87),("English", "Charlie", 91)
).toDF("subject", "name", "score")// 按科目分组
val grouped = studentScores.groupByKey(row => row.getAs[String]("subject"))

示例 1: 计算每科平均分

val subjectAverages = grouped.mapGroups { (subject, iterator) =>var total = 0var count = 0while (iterator.hasNext) {val row = iterator.next()total += row.getAs[Int]("score")count += 1}(subject, if (count > 0) total.toDouble / count else 0.0)
}.toDF("subject", "average_score")subjectAverages.show()

输出结果:

+--------+------------------+
| subject|     average_score|
+--------+------------------+
|   Math|              85.0|
|Science|              88.33|
|English|              89.33|
+--------+------------------+

示例 2: 找出每科最高分和学生

val topScores = grouped.mapGroups { (subject, iterator) =>var maxScore = Int.MinValuevar topStudent = ""while (iterator.hasNext) {val row = iterator.next()val score = row.getAs[Int]("score")val name = row.getAs[String]("name")if (score > maxScore) {maxScore = scoretopStudent = name}}(subject, topStudent, maxScore)
}.toDF("subject", "top_student", "top_score")topScores.show()

输出结果:

+--------+-----------+---------+
| subject|top_student|top_score|
+--------+-----------+---------+
|   Math|        Bob|       92|
|Science|        Bob|       95|
|English|    Charlie|       91|
+--------+-----------+---------+

示例 3: 计算每科成绩分布(统计各分数段人数)

val scoreDistribution = grouped.mapGroups { (subject, iterator) =>var excellent = 0  // 90-100var good = 0       // 80-89var average = 0    // 70-79var below = 0      // <70while (iterator.hasNext) {val row = iterator.next()val score = row.getAs[Int]("score")if (score >= 90) excellent += 1else if (score >= 80) good += 1else if (score >= 70) average += 1else below += 1}(subject, excellent, good, average, below)
}.toDF("subject", "excellent", "good", "average", "below_70")scoreDistribution.show()

输出结果:

+--------+---------+----+-------+-------+
| subject|excellent|good|average|below_70|
+--------+---------+----+-------+-------+
|   Math|        1|   1|      1|      0|
|Science|        1|   2|      0|      0|
|English|        1|   2|      0|      0|
+--------+---------+----+-------+-------+

示例 4: 为每科生成成绩报告

val subjectReports = grouped.mapGroups { (subject, iterator) =>var students = List[String]()var scores = List[Int]()var total = 0var count = 0while (iterator.hasNext) {val row = iterator.next()val name = row.getAs[String]("name")val score = row.getAs[Int]("score")students = name :: studentsscores = score :: scorestotal += scorecount += 1}val average = if (count > 0) total.toDouble / count else 0.0val maxScore = if (scores.nonEmpty) scores.max else 0val minScore = if (scores.nonEmpty) scores.min else 0s"Subject: $subject | Students: ${students.mkString(", ")} | " +s"Average: $average | Max: $maxScore | Min: $minScore"
}.toDF("report")subjectReports.show(false)

输出结果:

+---------------------------------------------------------------------------+
|report                                                                     |
+---------------------------------------------------------------------------+
|Subject: Math | Students: Charlie, Bob, Alice | Average: 85.0 | Max: 92 | Min: 78|
|Subject: Science | Students: Charlie, Bob, Alice | Average: 88.33 | Max: 95 | Min: 82|
|Subject: English | Students: Charlie, Bob, Alice | Average: 89.33 | Max: 91 | Min: 87|
+---------------------------------------------------------------------------+

示例 5: 计算每科成绩的标准差

val subjectStdDev = grouped.mapGroups { (subject, iterator) =>var scores = List[Double]()var sum = 0.0var count = 0// 第一次遍历:计算平均值while (iterator.hasNext) {val row = iterator.next()val score = row.getAs[Int]("score").toDoublescores = score :: scoressum += scorecount += 1}if (count == 0) {(subject, 0.0)} else {val mean = sum / count// 第二次遍历:计算方差var variance = 0.0scores.foreach(score => {variance += Math.pow(score - mean, 2)})variance /= count// 计算标准差val stdDev = Math.sqrt(variance)(subject, stdDev)}
}.toDF("subject", "std_dev")subjectStdDev.show()

输出结果:

+--------+------------------+
| subject|           std_dev|
+--------+------------------+
|   Math| 5.88784057761515|
|Science|5.507570547286102|
|English|1.699673171197595|
+--------+------------------+

示例 6: 为每个科目创建自定义摘要

val customSummaries = grouped.mapGroups { (subject, iterator) =>// 收集所有数据val data = iterator.toList.map(row => (row.getAs[String]("name"), row.getAs[Int]("score")))// 排序val sorted = data.sortBy(-_._2)// 计算统计量val scores = sorted.map(_._2)val average = scores.sum.toDouble / scores.lengthval median = if (scores.length % 2 == 1) {scores(scores.length / 2)} else {(scores(scores.length / 2 - 1) + scores(scores.length / 2)) / 2.0}// 创建自定义摘要val summary = Map("subject" -> subject,"top_student" -> sorted.head._1,"top_score" -> sorted.head._2,"average" -> average,"median" -> median,"student_count" -> scores.length)summary
}.toDF("summary")customSummaries.show(false)

输出结果:

+-----------------------------------------------------------------------------------------+
|summary                                                                                  |
+-----------------------------------------------------------------------------------------+
|Map(subject -> Math, top_student -> Bob, top_score -> 92, average -> 85.0, median -> 85.0, student_count -> 3)|
|Map(subject -> Science, top_student -> Bob, top_score -> 95, average -> 88.33, median -> 88.0, student_count -> 3)|
|Map(subject -> English, top_student -> Charlie, top_score -> 91, average -> 89.33, median -> 90.0, student_count -> 3)|
+-----------------------------------------------------------------------------------------+

注意事项

  1. 内存使用mapGroups 会将整个分组的数据加载到内存中,因此对于非常大的分组,可能会导致内存不足的问题。

  2. 性能考虑:对于简单的聚合操作(如求和、计数),使用 Spark 内置的聚合函数通常比 mapGroups 更高效。

  3. 数据倾斜:如果某些分组特别大,可能会导致任务执行时间过长。

  4. 迭代器使用mapGroups 提供的迭代器只能遍历一次,如果需要多次访问数据,需要先将其转换为列表或数组。

  5. 类型安全:使用 mapGroups 时,返回的数据类型需要与预期的输出类型匹配,否则可能会在运行时出现错误。

mapGroups 是一个非常灵活的函数,适用于需要自定义复杂分组逻辑的场景。通过上述示例,你可以看到它可以用于各种统计计算、数据转换和报告生成任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/95602.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95602.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/95602.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图论】Graphs.jl 图数据的读写与生成器

文章目录图数据的读写Graphs.loadgraphGraphs.loadgraphsGraphs.savegraph保存单个图保存图字典Graphs.loadlg_multGraphs.savelgGraphs.savelg_mult图的生成器1. 随机图模型1.1 Erdős–Rnyi 模型1.2 巴拉巴西-阿尔伯特模型 (无标度网络)1.3 小世界网络模型1.4 随机块模型 (SB…

Go指针全解析:从基础到实战

基本概念与定义指针的定义指针是一种特殊的变量类型&#xff0c;它存储的不是实际数据值&#xff0c;而是另一个变量在计算机内存中的地址。在底层实现上&#xff0c;指针本质上是保存内存位置的无符号整数&#xff0c;它直接指向内存中的特定位置&#xff0c;允许程序直接操作…

Oracle 查询有哪些用户 提示用户名密码无效

要查询 Oracle 数据库中的所有用户&#xff0c;可以使用以下 SQL 查询语句。这个查询将返回数据库中所有用户的列表。 [] SELECT username FROM all_users ORDER BY username;如果你有足够的权限&#xff08;通常是 DBA 权限&#xff09;&#xff0c;你也可以使用 dba_users 视…

小白成长之路-develops -jenkins部署lnmp平台

文章目录一、准备工作1.1两台虚拟机1.2配置文件1.3免密登录二、实战1.构建主item2.测试nginx,php,mysql2.1新建测试项目2.2与正式项目绑定构建后的操作2.3测试2.4导入discuz项目总结一、准备工作 1.1两台虚拟机 服务器&#xff1a;192.168.144.24 客户端&#xff1a;192.168.…

【HarmonyOS 6】仿AI唤起屏幕边缘流光特效

【HarmonyOS 6】仿AI唤起屏幕边缘流光特效 一、前言 最近在做 HarmonyOS 6.0 的适配&#xff0c;发现 Beta1版本里多了个很实用的视效功能——自带背景的双边流光。 之前做屏幕边缘流光特效的时候&#xff0c;要么得自己写渐变动画拼效果&#xff0c;要么就得套好几个组件叠层&…

跟做springboot尚品甄选项目

springbootvue3 【尚硅谷Java项目《尚品甄选》 SpringBootSpringCloud萌新学会企业级java项目】003.后台系统-搭建前端环境&#xff08;工程创建&#xff09;_哔哩哔哩_bilibili E:\project\AllProJect\Shangpin Selection\项目材料素材\课件\尚品甄选项目课件 前端套用框架…

【Linux】创建线程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 文章目录 一、为什么需要线程&#xff1f; 创建线程 示例&#xff1a;计算斐波恩夕法 一、为什么需要线程&#xff1f; 在多核处理器的计算机上&#xff0c;线程可…

HTML应用指南:利用POST请求获取全国九号电动车体验店服务店位置信息

九号公司(Ninebot)作为全球领先的智能短途出行解决方案提供商,始终秉持“智慧移动,愉悦生活”的品牌理念,致力于为个人用户打造安全、智能、时尚的城市出行体验。依托“智能硬件 + 数字服务 + 线下触点”三位一体的战略布局,九号公司已建立起覆盖全国、辐射全球的销售与服…

Kafka面试精讲 Day 4:Consumer消费者模型与消费组

【Kafka面试精讲 Day 4】Consumer消费者模型与消费组 在“Kafka面试精讲”系列的第四天&#xff0c;我们将深入探讨Kafka的核心组件之一——Consumer消费者模型与消费组&#xff08;Consumer Group&#xff09;。这是Kafka实现高吞吐、可扩展消息消费的关键机制&#xff0c;也…

使用 Uni-app 打包 外链地址APK 及 iOS 注意事项

本文详细介绍了如何使用 Uni-app 框架将项目打包为 Android APK 和 iOS 应用&#xff0c;重点讲解了 minSdkVersion、targetSdkVersion 和 abiFilters 的配置&#xff0c;以及 iOS 开发的注意事项。文章还包含了您提供的 WebView 示例代码&#xff0c;并提供了关键的注意事项&a…

异常处理小妙招——3.构造函数的安全第一原则:为什么不在构造函数中抛出异常?

文章目录灾难性的生日派对构造函数&#xff1a;对象的出生证明安全第一&#xff1a;严格的出生检查为什么要在构造函数中严格验证&#xff1f;1. 避免"僵尸对象"2. Fail-Fast&#xff08;快速失败&#xff09;原则现实世界的实践建议1. 使用工厂方法模式2. 使用Build…

iptables 和 ip route

文章目录iptables原理及常用命令表链链表链表总结iptables 常用命令及参数1. 规则管理命令 (Commands)2. 规则匹配参数 (Rule-Specification - Matches)3. 目标动作参数 (Target)命令示例配置流程示例ip route常用命令iptables和ip route的联系实用命令示例对比iptables原理及常…

RPC和HTTP的区别?

RPC和HTTP是两种不同的通信协议&#xff0c;它们在通信方式、性能效率以及灵活性可扩展性等方面存在区别。以下是具体分析&#xff1a; 通信方式 RPC&#xff1a;RPC是基于远程过程调用的二进制协议&#xff0c;它允许客户端像调用本地函数一样调用远程服务器上的函数或方法[2]…

贝叶斯分类(Bayes Classify)

一. 核心思想贝叶斯分类是一类基于贝叶斯定理&#xff08;Bayes Theorem&#xff09;和概率统计的分类算法&#xff0c;核心思想是 “通过已知的先验概率&#xff0c;结合数据的似然性&#xff0c;计算后验概率&#xff0c;最终将样本归为后验概率最高的类别”。它在机器学习、…

怎么熟悉业务,我是做前端的,但对业务了解没有渠道

作为前端开发者&#xff0c;想深入了解业务但“没有渠道”&#xff0c;这是非常普遍的痛点。很多前端同学只接到“切图实现页面”的任务&#xff0c;久而久之就成了“实现工具人”。但业务理解力&#xff0c;恰恰是区分“初级”和“高级”前端的核心分水岭。 好消息是&#xff…

如何批量在PDF文档最后一页盖章?

在面对上百份需要处理的 PDF 文档时&#xff0c;逐个打开文档盖章再进行保存&#xff0c;这些步骤不仅提高我们工作的繁琐&#xff0c;还容易导致处理位置错误或遗漏。那么怎么去将 PDF 文档末页实现批量自动打上电子印章&#xff1f;一般的方式没有办法来满足我们高效率办公的…

Keras/TensorFlow 中 `predict()` 函数详细说明

Keras/TensorFlow 中 predict() 函数详细说明 predict() 是 Keras/TensorFlow 中用于模型推理的核心方法&#xff0c;用于对输入数据生成预测输出。下面我将从多个维度全面介绍这个函数的用法和细节。 一、基础语法和参数 基本形式 predictions model.predict(x,batch_sizeNon…

题解:UVA1589 象棋 Xiangqi

看到代码别急着走&#xff0c;还要解释呢&#xff01;哈哈&#xff0c;知道这个题我是怎么来的吗&#xff1f;和爸爸下象棋20场输17场和2场QWQ于是乎我就想找到一个可以自动帮我下棋的程序&#xff0c;在洛谷上面搜索&#xff0c;就搜索到了这个题。很好奇UVA的为啥空间限制是0…

基于YOLOv11的脑卒中目标检测及其完整数据集——推动智能医疗发展的新机遇!

在当今科技迅速发展的时代&#xff0c;脑卒中作为一种严重威胁人类健康的疾病&#xff0c;其早期的检测和及时的干预显得尤为重要。为此&#xff0c;本项目推出基于YOLOv11的脑卒中目标检测系统&#xff0c;结合完整的数据集&#xff0c;不仅提高了检测的效率&#xff0c;更为医…

sed——Stream Editor流编辑器

文章目录前言一、什么是sed二、sed的原理2.1 sed工作流程的三个步骤2.2 sed的两个重要空间&#xff1a;2.3 sed的具体运作流程三、sed的常见用法3.1 sed的基本格式3.2 常用选项3.3 常用操作3.3.1 基本语法规则3.3.2 常用操作命令3.4 操作用法示例3.4.1 输出符合条件的文本&…