RDD键值对的应用——一个简单的例子对比用与不用键值对的差别

有关RDD编程(Python版)的基础操作可参考:spark:RDD编程(Python版)

初看题目

先来看一道比较简单的用 pyspark交互式环境的编程题目:

该数据集包含了某大学计算机系的成绩,数据格式如下所示:
Tom,DataBase,80
Tom,Algorithm,50
Tom,DataStructure,60
Jim,DataBase,90
Jim,Algorithm,60
Jim,DataStructure,80
……
请根据给定的实验数据,在pyspark中通过编程来计算以下内容:
(1)该系总共有多少学生;
(2)该系共开设了多少门课程;
(3)Tom同学的总成绩平均分是多少;
(4)求每名同学的选修的课程门数;
(5)该系DataBase课程共有多少人选修;
(6)各门课程的平均分是多少;

想要完成这道题目的难度并不大,第(1)(2)(3)(5)不需要构建RDD键值对,没有太多的争议,直接操作RDD即可:

(1)该系总共有多少学生

>>> lines = sc.textFile("file:///opt/spark/sparksqldata/Data01.txt")
>>> res = lines.map(lambda x:x.split(",")).map(lambda x: x[0]) #获取每行数据的第 1 列
>>> distinct_res = res.distinct() #去重操作
>>> distinct_res.count()  #取元素总个数
265

答案为:265 人

(2)该系共开设了多少门课程

>>> lines = sc.textFile("file:///opt/spark/sparksqldata/Data01.txt")
>>> res = lines.map(lambda x:x.split(",")).map(lambda x:x[1]) #获取每行数据的第 2 列
>>> distinct_res = res.distinct() #去重操作
>>> distinct_res.count() #取元素总个数
8

答案为 :8 门

(3)Tom同学的总成绩平均分是多少

>>> lines = sc.textFile("file:///opt/spark/sparksqldata/Data01.txt")
>>> res = lines.map(lambda x:x.split(",")).filter(lambda x:x[0]=="Tom")  #筛选 Tom 同学的成绩信息
>>> res.foreach(print)
26
12
16
40
60
>>> score = res.map(lambda x:int(x[2])) #提取 Tom 同学的每门成绩,并转换为 int 类型
>>> num = res.count()  #Tom 同学选课门数
>>> sum_score = score.reduce(lambda x,y:x+y)  #Tom 同学的总成绩
>>> avg = sum_score/num  #总成绩/门数=平均分
>>> print(avg)
30.8

答案为:30.8 分

(5)该系DataBase课程共有多少人选修

>>> lines = sc.textFile("file:///opt/spark/sparksqldata/Data01.txt")
>>> res = lines.map(lambda x:x.split(",")).filter(lambda x:x[1]=="DataBase")
>>> res.count()
126

答案为:126人


接下来重点讨论第(4)(6)题用于不用键值对的区别

用与不用键值对的区别

(4)求每名同学的选修的课程门数

要想统计出每名学生选修的课程门数,即统计出每个学生的名字在数据集中出现了几次即可,
在不用键值对的情况下可采用 map + lambda表达式 +列表解析 的格式记录每个名字出现的次数:

>>> lines = sc.textFile("file:///opt/spark/sparksqldata/Data01.txt")
>>> data_local = lines.collect()  # 将lines中的数据放入列表
>>> stuname = lines.map(lambda line: line.split(",")[0]).distinct()  # 构建去重后的学生姓名的rdd
>>> each_res = stuname.map(lambda x :(x, len([line for line in data_local if x in line])))  # 以列表解析是形式查找每个学生名字出现的次数
>>> each_res.foreach(print)
('Lewis', 4)
('Mike', 3)
('Walter', 4)
('Lewis', 4)
('Mike', 3)
('Walter', 4)
......

而如果采取构建键值对的方式就不需要多次调用 collect() ,也不需要使用列表解析,直接使用RDD键值对的常见操作 reduceByKey() 即可

>>> lines = sc.textFile("file:///opt/spark/sparksqldata/Data01.txt")
>>> res = lines.map(lambda x:x.split(",")).map(lambda x:(x[0],1))  # 学生每门课程都对应(学生姓名,1),学生有 n 门课程则有 n 个(学生姓名,1)
>>> each_res = res.reduceByKey(lambda x,y: x+y)  #按学生姓名获取每个学生的选课总数
>>> each_res.foreach(print)
('Lewis', 4)
('Mike', 3)
('Walter', 4)
('Lewis', 4)
('Mike', 3)
('Walter', 4)
......

(6)各门课程的平均分是多少

要想统计出每门课程的平均分,即统计出每门课程的分数和去除以该课程在数据集中出现的次数,相较于(4),仅多了个求和操作,需要遍历每一个成绩的值,便先对lines进行 split() 操作,再用 collect() 将数据存入列表,使用两个列表解析(分别求 sum 和 len)后作商即可:

>>> lines = sc.textFile("file:///opt/spark/sparksqldata/Data01.txt")
>>> coursename_score = lines.map(lambda line: (line.split(",")[1], line.split(",")[2])).collect()
>>> coursename =  lines.map(lambda line: line.split(",")[1]).distinct() # 构建去重后的科目的rdd
>>> avg =  coursename.map(lambda x:(x, sum([int(line[1]) for line in 
...coursename_score if x in line]) / len([line for line in 
...coursename_score if x in line])))
>>> avg.foreach(print)
('Software', 50.90909090909091)
('OperatingSystem', 54.940298507462686)
('Python', 57.8235294117647)
('ComputerNetwork', 51.901408450704224)
('DataBase', 50.53968253968254)
('Algorithm', 48.833333333333336)
('DataStructure', 47.57251908396947)
('CLanguage', 50.609375)

采用构建键值对的方式同样可以很简洁直观地达到效果:

>>> lines = sc.textFile("file:///opt/spark/sparksqldata/Data01.txt")
>>> res = lines.map(lambda x:x.split(",")).map(lambda x:(x[1],(int(x[2]),1))) # 为每门课程的分数后面新增一列 1,表示 1 个学生选择了该课程。格式如('ComputerNetwork', (44, 1))
>>> temp = res.reduceByKey(lambda x,y:(x[0]+y[0],x[1]+y[1])) #按课程名聚合课程总分和选课人数。格式如('ComputerNetwork', (7370, 142))
>>> avg = temp.map(lambda x:(x[0], round(x[1][0]/x[1][1],2)))  #课程总分/选课人数 = 平均分,并利用 round(x,2)保留两位小数
>>> avg.foreach(print)
('Software', 50.90909090909091)
('OperatingSystem', 54.940298507462686)
('Python', 57.8235294117647)
('ComputerNetwork', 51.901408450704224)
('DataBase', 50.53968253968254)
('Algorithm', 48.833333333333336)
('DataStructure', 47.57251908396947)
('CLanguage', 50.609375)

虽然这只是一个很简单的例子,数据量较少,但也能从中看出RDD键值对操作可提供更高效且更灵活的数据处理方式,当数据量较为庞大时,RDD键值对操作能使得分布式计算框架处理更加大规模且复杂的数据集。

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

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

相关文章

CamSim相机模拟器:极大加速图像处理开发与验证过程

随着图像处理技术的不断发展,相机模拟在图像处理开发和验证中扮演着越来越重要的角色。相机模拟能够模拟真实相机的成像过程,提供高质量的图像输入,使开发人员能够更好地评估和调整图像处理算法。本文将探讨如何通过相机模拟来加速图像处理的…

Docker的基础使用

Docker的基础使用 Docker 是一个开放平台,用于开发、运输和运行应用程序。Docker 允许你将应用程序与基础架构分离,从而可以像管理应用程序一样快速交付软件。以下是 Docker 的详细使用指南: 安装 Docker 下载 Docker : 根据你的操作系统…

vue实现H5拖拽可视化编辑器

一款专注可视化平台工具&#xff0c;功能强大&#xff0c;高可扩展的HTML5可视化编辑器&#xff0c;致力于提供一套简单易用、高效创新、无限可能的解决方案。技术栈采用vue和typescript开发, 专注研发创新工具。 <template><div:style"style":class"…

MYSQL数据库的安全管理-数据库实验六

Mysql数据库实验及练习题相关 MySQL 数据库和表的管理-数据库实验一 MySQL连接查询、索引、视图-数据库实验二、实验三 MySQL约束、触发器-数据库实验四 MYSQL存储过程和存储函数-数据库实验五 MySQL批量随机生成name、TEL、idNumber MYSQL数据库的安全管理-数据库实验六 MYSQ…

msvcr120.dll丢失的解决方法

msvcr120.dll丢失的解决方法 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我将为大家分享一个常见但可能令人头痛的问题的解决方法——“msvcr12…

<JavaEE> TCP 的通信机制(二) -- 连接管理(三次握手和四次挥手)

目录 TCP的通信机制的核心特性 三、连接管理 1&#xff09;什么是连接管理&#xff1f; 2&#xff09;“三次握手”建立连接 1> 什么是“三次握手”&#xff1f; 2> “三次握手”的核心作用是什么&#xff1f; 3&#xff09;“四次挥手”断开连接 1> 什么是“…

【JavaWeb】函数式接口(学习笔记)

一、函数式接口概述 定义&#xff1a;有且只有一个抽象方法 注解&#xff1a;FunctionalInterface 函数式接口作为参数&#xff1a;Lambda表达式作为参数传递 函数式接口作为返回值&#xff1a;Lambda表达式作为结果返回 二、Supplier接口 Supplier<T>&#xff1a;…

Ubuntu安装WordPress并使用Nginx作为Web服务器

在Ubuntu上安装和配置WordPress并使用Nginx作为Web服务器&#xff0c;以下是一个简单的操作流程&#xff1a; 步骤 1: 安装Nginx bashCopy code sudo apt update sudo apt install nginx 启动Nginx并设置开机自启&#xff1a; sudo systemctl start nginx sudo systemctl e…

第2课 用FFmpeg读取rtmp流并显示视频

这节课我们开始利用ffmpeg和opencv来实现一个rtmp播放器。播放器的最基本功能其实就两个:显示画面和播放声音。在实现这两个功能前&#xff0c;我们需要先用ffmpeg连接到rtmp服务器&#xff0c;当然也可以打开一个文件。 1.压缩备份上节课工程文件夹为demo.rar&#xff0c;并修…

版权登记是怎么个流程?都需要准备些什么材料?

版权登记是指按照规定的程序和条件&#xff0c;向版权局或相关机构提交申请&#xff0c;对作品进行登记和记录的过程。版权登记是一种法律手段&#xff0c;旨在保护创作者的权益和作品的完整性&#xff0c;防止盗版和侵权行为。 版权登记的申请范围包括但不限于文字作品、口述…

ZETA落地合肥、宜城南方水泥,纵行科技携手中才邦业助力水泥企业数智化管理

近日&#xff0c;合肥南方水泥、宜城南方水泥落地ZETA预测性维护方案&#xff0c;通过在水泥厂内搭建ZETA网络&#xff0c;并在B类及C类主辅机设备上安装ZETA系列端智能传感器&#xff0c;进行数据采集和监测设备运行状态、以及早期故障警报和诊断&#xff0c;实现水泥生产设备…

web期末大作业--网页设计 HTML+CSS+JS(附源码)

目录 一&#xff0c;作品介绍 二.运用知识 三.作品详情 四.部分作品效果图 我的&#xff1a;​编辑 五.部分源代码 六.文件目录 七.源码 一&#xff0c;作品介绍 作品介绍&#xff1a;该作品是一个是一个关于影视作品的网页&#xff0c;一共有五个页面&#xff0c;主页&a…

文件IO

文章目录 文章目录 前言 一 . 文件 文件路径 文件类型 Java中操作文件 File 概述 属性 构造方法 方法 createNewFile mkdir 二 . 文件内容的读写 - IO InputStream 概述 FileInputStream 概述 利用 Scanner 进行字符读取 OutputStream 概述 PrintWriter封装O…

gin框架使用系列之五——表单校验

系列目录 《gin框架使用系列之一——快速启动和url分组》《gin框架使用系列之二——uri占位符和占位符变量的获取》《gin框架使用系列之三——获取表单数据》《gin框架使用系列之四——json和protobuf的渲染》 一 、表单验证的基本理论 在第三篇中&#xff0c;我们介绍了如何…

SpringIOC-注解式

IOC操作Bean管理(基于注解方式) 1.什么是注解(1)注解是代码的特殊标记, 格式 注解名(属性名值,属性2值2)(2)使用注解,注解作用在 类上面,方法上,属性上(3)使用注解目的: 简化xml配置2.spring针对bean 管理中创建对象提供注解(1) Component (2) Service(3) Controller(4) Repo…

Flink1.17实战教程(第四篇:处理函数)

系列文章目录 Flink1.17实战教程&#xff08;第一篇&#xff1a;概念、部署、架构&#xff09; Flink1.17实战教程&#xff08;第二篇&#xff1a;DataStream API&#xff09; Flink1.17实战教程&#xff08;第三篇&#xff1a;时间和窗口&#xff09; Flink1.17实战教程&…

Hadoop集群找不到native-hadoop

1.问题描述 hive 运行中的问题&#xff0c;需要把把native复制进去 /usr/lib 2023-02-15 19:59:42,165 WARN scheduler.TaskSetManager: Lost task 11.0 in stage 1.0 (TID 3, common4, executor 2): java.lang.RuntimeException: Hive Runtime Error while closing operators…

获取当前进程cpu瞬时占用[linux][windows][c++]

linux #include <iostream> #include <fstream> #include <sstream> #include <unistd.h>class ProcessCPUMonitor { public:double getProcessCPUUsage() const {// 获取进程启动时间long startTime getProcessStartTime();// 获取进程的 CPU 时间l…

C# LINQ

一、前言 学习心得&#xff1a;C# 入门经典第8版书中的第22章《LINQ》 二、LINQ to XML 我们可以通过LINQ to XML来创造xml文件 如下示例&#xff0c;我们用LINQ to XML来创造。 <Books><CSharp Time"2019"><book>C# 入门经典</book><…

【Go语言入门:Go语言的数据结构】

文章目录 3.Go语言的数据结构&#xff1a;3.1. 指针3.2. struct&#xff08;结构体&#xff09;3.3. Map(映射,哈希&#xff09; 3.Go语言的数据结构&#xff1a; 简介&#xff1a; 在Go语言中&#xff0c;数据结构体可以分为四种类型&#xff1a;基础类型、聚合类型、引用类型…