当前位置: 首页 > news >正文

SparkSQL数据模型综合实践

文章目录

  • 1. 实战概述
  • 2. 实战步骤
    • 2.1 创建数据集
    • 2.2 创建数据模型对象
      • 2.2.1 创建常量
      • 2.2.2 创建加载数据方法
      • 2.2.3 创建过滤年龄方法
      • 2.2.4 创建平均薪水方法
      • 2.2.5 创建主方法
      • 2.2.6 查看完整代码
    • 2.3 运行程序,查看结果
  • 3. 实战小结

1. 实战概述

  • 在本次实战中,创建一个名为DataModelSpark SQL数据模型对象,用于演示如何加载数据集、过滤数据以及计算统计信息。首先,在项目根目录下创建data目录,并在其中创建了包含员工信息的employees.json文件。然后,创建DataModel对象,并定义spark常量以及三个方法:loadData()filterAge()avgSalary(),分别用于加载数据、过滤年龄大于20岁的员工和计算不同性别的平均工资。最后,在main()方法中调用这些方法来执行数据处理任务。

2. 实战步骤

2.1 创建数据集

  • 在项目根目录创建data目录
    在这里插入图片描述
  • data里创建employees.json
    在这里插入图片描述
{"name": "赵天宇", "gender": "男", "age": "19", "salary": "10000"}
{"name": "钱文博", "gender": "男", "age": "29", "salary": "8000"}
{"name": "孙志强", "gender": "男", "age": "39", "salary": "9000"}
{"name": "李明宇", "gender": "男", "age": "22", "salary": "11000"}
{"name": "周雨涵", "gender": "女", "age": "19", "salary": "14000"}
{"name": "吴美琪", "gender": "女", "age": "35", "salary": "10000"}

2.2 创建数据模型对象

  • 创建net.huawei.practice
    在这里插入图片描述

  • practice子包里创建DataModel对象
    在这里插入图片描述

2.2.1 创建常量

  • DataModel对象里创建spark常量
    在这里插入图片描述
// 获取或创建Spark会话对象                                  
val spark = SparkSession.builder() // 创建Builder对象  .appName("DataModel") // 设置应用程序名称                .master("local[*]") // 运行模式:本地运行                 .getOrCreate() // 获取或创建Spark会话对象                 

2.2.2 创建加载数据方法

  • loadData()方法的需求说明:其主要功能是加载指定路径的文件并生成 DataFrame。方法接受一个字符串类型的参数 filePath,表示文件的路径。执行流程包括使用 spark.read.json(filePath) 方法读取 JSON 文件并创建 DataFrame,然后将生成的 DataFrame 返回给调用者。此方法简化了从文件加载数据到 DataFrame 的过程,提高了数据处理的效率和便捷性。

  • 创建loadData()方法
    在这里插入图片描述

// 加载数据方法                                                
def loadData(): DataFrame = {                            // 加载数据得到数据帧对象                                         val fileDF = spark.read.json("data/employees.json")    // 返回数据帧对象                                             fileDF                                                 
}                                                        

2.2.3 创建过滤年龄方法

  • filterAge() 方法的需求说明:该方法用于过滤 DataFrame 中年龄大于20岁的数据,并将结果打印到控制台。方法接受一个 DataFrame 类型的参数 employeeDF,表示原始 JSON 文件对应的 DataFrame 实例对象。方法不返回任何值(返回类型为 Unit)。核心思路包括使用 DataFrame 的 filter 方法根据条件过滤数据,然后使用 show 方法打印过滤后的结果。此方法简化了数据过滤和展示的过程,有助于快速分析和查看特定条件下的数据。
  • 创建filterAge()方法
    在这里插入图片描述
// 过滤年龄方法                                           
def filterAge(employeeDF: DataFrame): Unit = {      // 过滤年龄大于20岁的员工                                   val filterAgeDF = employeeDF.filter("age > 20")   // 显示过滤后的数据                                       filterAgeDF.show()                                
}                                                   

2.2.4 创建平均薪水方法

  • avgSalary() 方法,其需求是计算并打印 DataFrame 中不同性别的平均收入。方法接受一个 DataFrame 类型的参数 employeeDF,表示原始 JSON 文件对应的 DataFrame 实例对象。方法不返回任何值(返回类型为 Unit)。核心思路包括使用 createOrReplaceTempView 方法将 DataFrame 注册为临时表,然后通过 SQL 查询计算不同性别的平均收入,最后使用 show 方法将结果打印到控制台。此方法简化了数据处理流程,有助于快速分析和展示特定统计信息。
  • 创建avgSalary()方法
    在这里插入图片描述
// 计算平均工资方法                                              
def avgSalary(employeeDF: DataFrame): Unit = {           // 根据输入参数注册临时表                                         employeeDF.createOrReplaceTempView("employee")         // 计算平均工资                                              val avgSalaryDF = spark.sql(                           s"""                                                 |SELECT                                           |  gender, avg(salary) AS avg_salary                 |FROM                                             |  employee                                       |GROUP BY                                         |  gender                                         |""".stripMargin                                  )                                                      // 显示平均工资                                              avgSalaryDF.show()                                     
}                                                        

2.2.5 创建主方法

  • main() 方法,该方法是程序的入口点,用于调用 filterAgeavgSalary 方法。main 方法接受一个 Array[String] 类型的参数 args,这些参数可以在程序执行时从外部传递,使得程序能够动态使用这些参数而无需修改代码。main 方法不返回任何值(返回类型为 Unit)。业务代码的核心思路是首先调用 loadData() 方法加载数据,然后将返回的 DataFrame 传递给 filterAgeavgSalary 方法进行处理。这种方法结构清晰,便于管理和扩展程序功能。
  • 创建main()方法
    在这里插入图片描述
// 主方法                                     
def main(args: Array[String]): Unit = {    // 调用过滤年龄方法                              filterAge(loadData())                    // 调用计算平均工资方法                            avgSalary(loadData())                    
}                                          

2.2.6 查看完整代码

package net.huawei.practiceimport org.apache.spark.sql.{DataFrame, SparkSession}/*** 功能:数据模型演示* 作者:华卫* 日期:2025年01月16日*/
object DataModel {// 获取或创建Spark会话对象val spark = SparkSession.builder() // 创建Builder对象.appName("DataModel") // 设置应用程序名称.master("local[*]") // 运行模式:本地运行.getOrCreate() // 获取或创建Spark会话对象// 加载数据方法def loadData(): DataFrame = {// 加载数据得到数据帧对象val fileDF = spark.read.json("data/employees.json")// 返回数据帧对象fileDF}// 过滤年龄方法def filterAge(employeeDF: DataFrame): Unit = {// 过滤年龄大于20岁的员工val filterAgeDF = employeeDF.filter("age > 20")// 显示过滤后的数据filterAgeDF.show()}// 计算平均工资方法def avgSalary(employeeDF: DataFrame): Unit = {// 根据输入参数注册临时表employeeDF.createOrReplaceTempView("employee")// 计算平均工资val avgSalaryDF = spark.sql(s"""|SELECT|  gender, avg(salary) AS avg_salary|FROM|  employee|GROUP BY|  gender|""".stripMargin)// 显示平均工资avgSalaryDF.show()}// 主方法def main(args: Array[String]): Unit = {// 调用过滤年龄方法filterAge(loadData())// 调用计算平均工资方法avgSalary(loadData())}
}

2.3 运行程序,查看结果

  • 运行DataModel对象
    在这里插入图片描述

3. 实战小结

  • 在本次拓展练习中,我们通过创建一个 SparkSQL 数据模型综合实践项目,深入理解了 Spark 中的数据模型和数据处理流程。首先,我们在项目根目录下创建了 data 目录,并在其中创建了 employees.json 文件,用于存储员工数据。接着,我们创建了 DataModel 对象,并在其中定义了 spark 常量和三个方法:loadData()filterAge()avgSalary(),分别用于加载数据、过滤年龄大于20岁的员工和计算不同性别的平均薪水。在 main() 方法中,我们调用了这些方法来执行数据处理任务。通过这个练习,我们不仅学会了如何在 Spark 中操作 DataFrame,还学会了如何将数据处理逻辑封装成方法,提高了代码的可读性和可维护性。此外,我们还学会了如何使用 SQL 查询来分析数据,这在处理结构化数据时非常有用。总的来说,这个练习帮助我们更好地理解了 SparkSQL 的数据模型和数据处理流程,为今后的数据处理工作打下了坚实的基础。

相关文章:

SparkSQL数据模型综合实践

文章目录 1. 实战概述2. 实战步骤2.1 创建数据集2.2 创建数据模型对象2.2.1 创建常量2.2.2 创建加载数据方法2.2.3 创建过滤年龄方法2.2.4 创建平均薪水方法2.2.5 创建主方法2.2.6 查看完整代码 2.3 运行程序,查看结果 3. 实战小结 1. 实战概述 在本次实战中&#…...

3 查找重复的电子邮箱(having与where区别,distinct去重使用)

3 查找重复的电子邮箱(having与where区别,distinct去重使用) 表: Person ---------------------- | Column Name | Type | ---------------------- | id | int | | email | varchar | ---------------------- id 是该…...

uniapp——App 监听下载文件状态,打开文件(三)

5 实现下载文件并打开 这里演示,导出Excel 表格 文章目录 5 实现下载文件并打开DEMO监听下载进度效果图为什么 totalSize 一直为0? 相关Api: downloader DEMO 提示: 请求方式支持:GET、POST;POST 方式需要…...

循环队列(C语言)

从今天开始我会开启一个专栏leetcode每日一题,大家互相交流代码经验,也当作我每天练习的自我回顾。第一天的内容是leetcode622.设计循环队列。 一、题目详细 设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO&#…...

数据可视化:让数据讲故事的艺术

目录 1 前言2 数据可视化的基本概念2.1 可视化的核心目标2.2 传统可视化手段 3 数据可视化在知识图谱中的应用3.1 知识图谱的可视化需求3.2 知识图谱的可视化方法 4 数据可视化叙事:让数据讲故事4.1 叙事可视化的关键要素4.2 数据可视化叙事的实现方法 5 数据可视化…...

雷电9最新版安装Magisk+LSPosd(新手速通)

大家好啊!我是NiJiMingCheng 我的博客:NiJiMingCheng 在安卓系统的定制与拓展过程中,获取 ROOT 权限以及安装各类框架是进阶玩家常用的操作,这可以帮助我们实现更多系统层面的个性化功能。今天,我将为大家详细介绍如何…...

Ubuntu 24.04 LTS 开启 SMB 服务,并通过 windows 访问

Ubuntu 24.04 LTS 背景资料 Ubuntu服务器折腾集Ubuntu linux 文件权限Ubuntu 空闲硬盘挂载到 文件管理器的 other locations Ubuntu开启samba和window共享文件 Ubuntu 配置 SMB 服务 安装 Samba 确保 Samba 已安装。如果未安装,运行以下命令进行安装&#xff…...

使用Websocket进行前后端实时通信

1、引入jar&#xff0c;spring-websocket-starter <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency> 2、配置websocket config import org.springframe…...

vue2使用flv.js在浏览器打开flv格式视频

组件地址&#xff1a;GitHub - bilibili/flv.js: HTML5 FLV Player flv.js 仅支持 H.264 和 AAC/MP3 编码的 FLV 文件。如果视频文件使用了其他编码格式就打不开。 flv.vue <template><div><el-dialog :visible.sync"innerVisibleFlv" :close-on-pre…...

OpenCV相机标定与3D重建(61)处理未校准的立体图像对函数stereoRectifyUncalibrated()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 为未校准的立体相机计算一个校正变换。 cv::stereoRectifyUncalibrated 是 OpenCV 库中的一个函数&#xff0c;用于处理未校准的立体图像对。该函…...

[cg] glProgramBinary

参考&#xff1a; glProgramBinary - OpenGL 4 Reference Pages opengl 通过gpu编译好的 shader 可以存储到二进制文件中&#xff0c;第二次使用的时候直接加载二进制文件即可&#xff0c; glProgramBinary用于加载shader的二进制数据 实列代码如下&#xff1a; // 假设已经…...

LeetCode hot 力扣热题100 二叉树的最大深度

class Solution { public:int maxDepth(TreeNode* root) {if (root nullptr) {return 0;}int l_depth maxDepth(root->left);int r_depth maxDepth(root->right);return max(l_depth, r_depth) 1;} }; 代码作用 该函数通过递归计算二叉树的最大深度&#xff08;从根节…...

速通Docker === 网络

目录 Docker网络详解 容器之间直接通信的弊端 &#xff08;一&#xff09;启动容器 &#xff08;二&#xff09;进入容器并发起请求 &#xff08;三&#xff09;请求流程 &#xff08;四&#xff09; 弊端分析 一、Docker网络基础 &#xff08;一&#xff09;容器IP分配…...

【MySQL — 数据库基础】深入解析MySQL常用数据类型

常用数据类型 创建完数据库之后&#xff0c;就要在数据库中创建表&#xff0c;表中存储的数据记录&#xff0c;一条记录由不同的列组成&#xff0c;每条列都需要自己的类型&#xff1b;并且表中的多个行对应的列的数据类型&#xff0c;都必须是相同的&#xff1b; 那么每个…...

Linux高级--3.3.1 C++ spdlog 开源异步日志方案

一、基本介绍 spdlog 是由 Gustav S. 在 2015 年开发的一个高性能 C 日志库。开发这个库的主要目的是为了提供一个非常快速、轻量、易于使用的日志工具&#xff0c;特别适合需要高性能、低延迟日志记录的 C 应用程序。&#xff08;由于源码现在比较难下载&#xff0c;我把压缩…...

电梯系统的UML文档05

Dispatcher 不控制实际的电梯组件&#xff0c;但它在软件系统中是重要的。每一个电梯有一个ispatcher&#xff0c;主要功能是计算电梯的移动方向、移动目的地以及保持门的打开时间。它和系统中除灯控制器以外的几乎所有控制对象交互。 安全装置也是一个环境对象&#xff0c;它…...

如何使 LLaMA-Factory 支持 google/gemma-2-2b-jpn-it 的微调

如何使 LLaMA-Factory 支持 google/gemma-2-2b-jpn-it 的微调 追加&#xff0c; "Gemma-2-2B-JPN-Instruct": {DownloadSource.DEFAULT: "google/gemma-2-2b-jpn-it",},修改 constants.py&#xff0c; vi ./src/llamafactory/extras/constants.py---"…...

MySQL中日期和时间戳的转换:字符到DATE和TIMESTAMP的相互转换

在MySQL中&#xff0c;经常需要在 DATE、TIMESTAMP 和字符串之间进行相互转换。以下是一些常见的转换方法&#xff1a; 1. 字符串到日期/时间类型 字符串转 DATE: 使用 STR_TO_DATE() 函数将字符串转换为 DATE 类型。你需要提供字符串的格式。 SELECT STR_TO_DATE(2024-08-24,…...

HarmonyOS NEXT开发进阶(十):UIAbility 组件交互

文章目录 一、前言二、启动应用内的 UIAbility三、启动应用内的UIAbility并获取返回结果四、启动其他应用的UIAbility五、启动其他应用的 UIAbility 并获取返回结果六、启动 UIAbility 的指定页面6.1 调用方 UIAbility 指定启动页面6.2 目标 UIAbility 首次启动6.3 目标UIAbili…...

深入探索Math.NET:开启高效数值计算之旅

一、引言 在当今数字化时代&#xff0c;数值计算已然成为科学研究、工程设计、金融分析等众多领域的核心驱动力。从探索宇宙奥秘的物理学计算&#xff0c;到优化建筑结构的土木工程设计&#xff0c;再到预测市场趋势的金融建模&#xff0c;数值计算的身影无处不在&#xff0c;…...

蓝牙抓包不求人:从HCI日志里‘挖’出Link Key的两种实用方法(附安卓路径)

蓝牙安全逆向实战&#xff1a;从HCI日志中提取Link Key的深度解析在蓝牙协议安全研究领域&#xff0c;Link Key作为设备配对认证的核心凭证&#xff0c;其获取方式一直是逆向工程师关注的焦点。许多安全审计场景下&#xff0c;我们往往只能获得加密后的HCI通信日志&#xff0c;…...

Claude本地化部署终极方案(企业级容器化全栈手册):支持Anthropic API兼容、流式响应、模型热切换与RBAC权限隔离

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;Claude本地化部署的架构全景与企业级价值定位 Claude本地化部署并非简单地将模型权重下载后运行&#xff0c;而是一套融合推理引擎优化、安全沙箱隔离、API网关治理与可观测性集成的端到端架构体系。其核心目…...

人类防伪指南:为什么你越写错字,HR越信你是真人?

前言各位码农、算法侠、CtrlC/V十级学者请注意&#xff1a;你有没有过这样的经历&#xff1f;辛辛苦苦肝了一晚上文档&#xff0c;逻辑严密、语法丝滑、连Markdown都对齐得像军训方阵&#xff0c;结果老板幽幽来一句&#xff1a;“这真是你自己写的&#xff1f;”那一刻&#x…...

AI圈内火热的Agent、MCP、Skill、CLI是啥?用装修房子讲透,看完秒懂

本文用装修房子的比喻&#xff0c;详细解释了AI领域的四个核心概念&#xff1a;Agent如同会自主规划任务的私人助理&#xff1b;MCP是AI与外部工具数据的统一接口&#xff0c;类似USB-C&#xff1b;Skill是指导AI按标准操作执行的手册&#xff1b;CLI则是不依赖图形界面的命令行…...

CSharpVerbalExpressions常见问题解答:解决开发者遇到的10个典型挑战

CSharpVerbalExpressions常见问题解答&#xff1a;解决开发者遇到的10个典型挑战 【免费下载链接】CSharpVerbalExpressions 项目地址: https://gitcode.com/gh_mirrors/cs/CSharpVerbalExpressions CSharpVerbalExpressions是一个强大的C#库&#xff0c;它通过类自然语…...

【python】ImportError: DLL load failed while importing QtWidgets: 找不到指定的程序。重新安装后搞定

文章目录前言一、PyQt6引用后报错二、使用步骤总结前言 想做个好看的界面&#xff0c;引用了PyQt6&#xff0c;却产生了新问题。 pip install pyqt6-tools&#xff0c;优先做这个动作进行修复。 一、PyQt6引用后报错 python里引用&#xff1a; from PyQt6.QtWidgets import…...

学习日志(三)【php语法学习,iscc校赛wp】

1. 任务 1.1.1.1.1.1. 知识部分 rce看【之前的笔记&#xff1f;】php的知识点学习继续jwt token好像是比赛的题目考察内容&#xff0c;我看看php伪协议 1.1.1.1.1.2. 题目 参加iscc比赛【五一】rce题目 1.1.1.1.1.3. 环境配置 把vscode搞好&#xff0c;上学期没有把Php配…...

深度解析:JetBrains IDE试用期重置机制的技术实现

深度解析&#xff1a;JetBrains IDE试用期重置机制的技术实现 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter 在软件开发工作流中&#xff0c;JetBrains IDE试用期管理是一个常见的技术挑战&#xff0c;尤其是在多…...

手机也能玩转无人机仿真:用安卓QGC App连接同一WiFi下的PX4 JMAVSim模拟器

手机也能玩转无人机仿真&#xff1a;用安卓QGC App连接同一WiFi下的PX4 JMAVSim模拟器 无人机开发者和爱好者们&#xff0c;是否曾想过用手机就能完成整个无人机仿真测试流程&#xff1f;告别笨重的电脑束缚&#xff0c;只需一部安卓设备&#xff0c;就能在沙发上调试飞控算法。…...

茉莉花插件:如何让中文文献管理效率提升300%

茉莉花插件&#xff1a;如何让中文文献管理效率提升300% 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件&#xff0c;用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum 还在为中文文献的元数据抓…...