Spark SQL【基于泰坦尼克号生还数据的 Spark 数据分析处理】

前言

        昨天实验课试着做了一个 Spark SQL 小案例,发现好多内容还是没有掌握,以及好多书上没有的内容需要学习。

一、数据准备

csv 文件内容部分数据展示:

PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
1,0,3,"Braund, Mr. Owen Harris",male,22,1,0,A/5 21171,7.25,,S
2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38,1,0,PC 17599,71.2833,C85,C
3,1,3,"Heikkinen, Miss. Laina",female,26,0,0,STON/O2. 3101282,7.925,,S
4,1,1,"Futrelle, Mrs. Jacques Heath (Lily May Peel)",female,35,1,0,113803,53.1,C123,S
5,0,3,"Allen, Mr. William Henry",male,35,0,0,373450,8.05,,S
6,0,3,"Moran, Mr. James",male,,0,0,330877,8.4583,,Q

字段说明

• PassengerId : 乘客编号。
• Survived : 是否存活,0表示未能存活,1表示存活。
• Pclass : 描述乘客所属的等级,总共分为三等,用1、2、3来描述:1表示高等;2表示中等;3表示低等。
• Name : 乘客姓名。
• Sex : 乘客性别。
• Age : 乘客年龄。
• SibSp : 与乘客同行的兄弟姐妹(Siblings)和配偶(Spouse)数目。
• Parch : 与乘客同行的家长(Parents)和孩子(Children)数目。
• Ticket : 乘客登船所使用的船票编号。
• Fare : 乘客上船的花费。
• Cabin : 乘客所住的船舱。
• Embarked : 乘客上船时的港口,C表示Cherbourg;Q表示Queenstown;S表示Southampton。

二、Spark数据预处理

1、通过读取本地文件生成 DataFrame 对象。

// 创建 SparkSession 对象val conf = new SparkConf().setMaster("local[*]").setAppName("practice1")val spark = SparkSession.builder().config(conf).getOrCreate()// 导入隐式转换相关依赖import spark.implicits._// 读取csv文件生成 DataFrame 对象val df = spark.read.format("csv").option("header","true").option("mode","DROPMALFORMED").load("data/practice1/titanic.csv")

2、修改字段类型

DataFrame 读取进来的都是 StringType 类型,我们需要对部分字段进行修改。

        'withColumn'是一个DataFrame转换函数,用于在现有的DataFrame上添加或替换列。这个函数接收两个参数,第一个是新列的名称,第二个是新列的值。对于新列的值,我们使用 cast 方法将它强制转为一个新的类型。

        cast方法用于将一个数据类型的值转换为另一个数据类型。它可以用于将一种数据类型转换为另一种数据类型,例如将字符串转换为整数或将整数转换为浮点数等。

withColumn 作为一个转换函数会返回一个新的 DataFrame 对象,记得通过变量或常量存储起来。

// 修改字段数据类型val md_df = df.withColumn("Pclass", df("Pclass").cast(IntegerType)) // 乘客登记 包括1-2-3三个等级.withColumn("Survived", df("Survived").cast(IntegerType)) //是否存活-1存活 0-未能存活.withColumn("Age", df("Age").cast(DoubleType)) // 年龄.withColumn("SibSp", df("SibSp").cast(IntegerType)) // 乘客的兄弟姐妹和配偶的数量.withColumn("Parch", df("Parch").cast(IntegerType)) //乘客的家长和孩子数目.withColumn("Fare", df("Fare").cast(DoubleType)) // 上传的花费

3、删除不必要的字段

// 删除不必要的字段val df1 = md_df.drop("PassengerId").drop("Name").drop("Ticket").drop("Cabin")

4、缺失值处理

用到的函数:

DSL 语句中的 select、where函数,以及 count 、zip 函数。

涉及到的操作:

RDD 对象转为 DataFrame 对象,这里因为RDD对象的内容是元组,所以可以直接调用 toDF 方法。 

统计缺失值

// 缺失值处理val columns: Array[String] = df1.columns  //返回df1的字段组成的数组 Array("字段1","字段2","字段3"...)// 通过select方法对字段数组中的每一个字段进行搜索,并通过where方法找出满足列col(字段).isNUll的值的count(个数)val missing_cnt: Array[Long] = columns.map(field => df1.select(col(field)).where(col(field).isNull).count())// 通过zip方法将两个集合数组合并成一个元组val tuples: Array[(Long, String)] = missing_cnt.zip(columns)// 把生成的元组读取为RDD对象再转为DataFrame对象val result_df: DataFrame = spark.sparkContext.parallelize(tuples).toDF("missing_cnt", "column_name")result_df.show()  // 统计缺失值

 统计结果展示:

+-----------+-----------+
|missing_cnt|column_name|
+-----------+-----------+
|          0|   Survived|
|          0|     Pclass|
|          0|        Sex|
|        177|        Age|
|          0|      SibSp|
|          0|      Parch|
|          0|       Fare|
|          2|   Embarked|
+-----------+-----------+

缺失值处理

// 处理缺失值函数def meanAge(dataFrame: DataFrame): Double = {dataFrame.select("Age").na.drop() //删除 Age 为空的行//'round' 函数用于将数字四舍五入到指定的小数位数。'mean' 函数则用于计算一组数值的平均值。.agg(round(mean("Age"), 0)) //对'Age'列计算平均值,并保留0位小数,也就是取整.first()  //由于agg操作返回的是一个DataFrame,而这个DataFrame只有一行,所以使用first()方法获取这一行。.getDouble(0) //从结果行中获取第一个字段(索引为0)的值,并将其转换为Double类型。}

处理: 

val df2 = df1.na.fill(Map("Age" -> meanAge(df1), "Embarked" -> "S"))df2.show()

处理结果展示:

+--------+------+------+----+-----+-----+-------+--------+
|Survived|Pclass|   Sex| Age|SibSp|Parch|   Fare|Embarked|
+--------+------+------+----+-----+-----+-------+--------+
|       0|     3|  male|22.0|    1|    0|   7.25|       S|
|       1|     1|female|38.0|    1|    0|71.2833|       C|
|       1|     3|female|26.0|    0|    0|  7.925|       S|
|       1|     1|female|35.0|    1|    0|   53.1|       S|
|       0|     3|  male|35.0|    0|    0|   8.05|       S|
|       0|     3|  male|30.0|    0|    0| 8.4583|       Q|
|       0|     1|  male|54.0|    0|    0|51.8625|       S|
|       0|     3|  male| 2.0|    3|    1| 21.075|       S|
|       1|     3|female|27.0|    0|    2|11.1333|       S|
|       1|     2|female|14.0|    1|    0|30.0708|       C|
|       1|     3|female| 4.0|    1|    1|   16.7|       S|
|       1|     1|female|58.0|    0|    0|  26.55|       S|
|       0|     3|  male|20.0|    0|    0|   8.05|       S|
|       0|     3|  male|39.0|    1|    5| 31.275|       S|
|       0|     3|female|14.0|    0|    0| 7.8542|       S|
|       1|     2|female|55.0|    0|    0|   16.0|       S|
|       0|     3|  male| 2.0|    4|    1| 29.125|       Q|
|       1|     2|  male|30.0|    0|    0|   13.0|       S|
|       0|     3|female|31.0|    1|    0|   18.0|       S|
|       1|     3|female|30.0|    0|    0|  7.225|       C|
+--------+------+------+----+-----+-----+-------+--------+
only showing top 20 rows

三、Spark 数据分析

1、891人当中,共多少人生还?

// 1.891人当中,共多少人生还?val survived_count: DataFrame = df2.groupBy("Survived").count()survived_count.show()
//保存结果到本地 
survived_count.coalesce(1).write.option("header","true").csv("output/practice1/survived_count.csv")

运行结果: 

+--------+-----+
|Survived|count|
+--------+-----+
|       1|  342|
|       0|  549|
+--------+-----+

2.不同上船港口生还情况

// 2.不同上船港口生还情况val survived_embark = df2.groupBy("Embarked", "Survived").count()survived_embark.show()survived_embark.coalesce(1).write.option("header","true").csv("data/practice1survived_embark.csv")

运行结果:

+--------+--------+-----+
|Embarked|Survived|count|
+--------+--------+-----+
|       Q|       1|   30|
|       S|       0|  427|
|       S|       1|  219|
|       C|       1|   93|
|       Q|       0|   47|
|       C|       0|   75|
+--------+--------+-----+

3.存活/未存活的男女数量及比例

 // 3.存活/未存活的男女数量及比例val survived_sex_count=df2.groupBy("Sex","Survived").count()val survived_sex_percent=survived_sex_count.withColumn("percent",format_number(col("count").divide(functions.sum("count").over()).multiply(100),5));survived_sex_percent.show()survived_sex_percent.coalesce(1).write.option("header", "true").csv("data/practice1/survived_sex_percent.csv")

运行结果:

+------+--------+-----+--------+
|   Sex|Survived|count| percent|
+------+--------+-----+--------+
|  male|       0|  468|52.52525|
|female|       1|  233|26.15039|
|female|       0|   81| 9.09091|
|  male|       1|  109|12.23345|
+------+--------+-----+--------+

4. 不同级别乘客生还人数和占总生还人数的比例

// 4. 不同级别乘客生还人数和占总生还人数的比例val survived_df = df2.filter(col("Survived")===1)val pclass_survived_count=survived_df.groupBy("Pclass").count()val pclass_survived_percent=pclass_survived_count.withColumn("percent",format_number(col("count").divide(functions.sum("count").over()).multiply(100),5));pclass_survived_percent.show()pclass_survived_percent.coalesce(1).write.option("header", "true").csv("data/practice1/pclass_survived_percent.csv")

运行结果:

+------+-----+--------+
|Pclass|count| percent|
+------+-----+--------+
|     1|  136|39.76608|
|     3|  119|34.79532|
|     2|   87|25.43860|
+------+-----+--------+

5. 有无同行父母/孩子的生还情况

 // 5.有无同行父母/孩子的生还情况val df4=df2.withColumn("Parch_label",when(df2("Parch")>0,1).otherwise(0))val parch_survived_count=df4.groupBy("Parch_label","Survived").count()parch_survived_count.show()parch_survived_count.coalesce(1).write.option("header", "true").csv("data/practice1/parch_survived_count.csv")

运行结果:

+-----------+--------+-----+
|Parch_label|Survived|count|
+-----------+--------+-----+
|          1|       0|  104|
|          1|       1|  109|
|          0|       0|  445|
|          0|       1|  233|
+-----------+--------+-----+

6.按照年龄,将乘客划分为未成年人、青年人、中年人和老年人,分析四个群体生还情况

    // 6.按照年龄,将乘客划分为未成年人、青年人、中年人和老年人,分析四个群体生还情况val df3=survived_df.withColumn("Age_label",when(df2("Age")<=18,"minor").when(df2("Age")>18 && df2("Age")<=35,"young").when(df2("Age")>35 && df2("Age")<=55,"middle").otherwise("older"))val age_survived=df3.groupBy("Age_label","Survived").count()age_survived.show()age_survived.coalesce(1).write.option("header", "true").csv("data/practice1/age_survived.csv")

运行结果:

+---------+--------+-----+
|Age_label|Survived|count|
+---------+--------+-----+
|    young|       1|  189|
|    older|       1|   12|
|    minor|       1|   70|
|   middle|       1|   71|
+---------+--------+-----+

7. 提取乘客等级和上船费用信息

    // 7.提取乘客等级和上船费用信息val sef = Seq("Pclass", "Fare")val df5 = df2.select(sef.head, sef.tail: _*)df5.show(5)df5.coalesce(1).write.option("header", "true").csv("data/practice1/pclass_fare.csv")

运行结果:

+------+-------+
|Pclass|   Fare|
+------+-------+
|     3|   7.25|
|     1|71.2833|
|     3|  7.925|
|     1|   53.1|
|     3|   8.05|
+------+-------+
only showing top 5 rows

四、数据可视化

数据可视化部分打算在学完 R 语言再完成,Python 实现后续更新。

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

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

相关文章

聊天机器人

收集窗帘相关的数据 可以用gpt生成&#xff0c;也可以用爬虫 图形化界面 gradio 向量数据库 faiss python代码 import gradio as gr import random import timefrom typing import Listfrom langchain.embeddings.openai import OpenAIEmbeddings from langchain.vectorstor…

揭秘:WhatsApp的注册策略

WhatsApp账号的注册方式可以分为两种&#xff1a;实体卡注册和虚拟卡注册。实体卡注册是指使用个人手机卡完成注册&#xff0c;而虚拟卡注册则通过前面提到的对接平台来完成的。 账号注册问题一直是导致WhatsApp账号永久封禁的主要原因。由于WhatsApp广泛为群发获客等用途之一…

设计方法编写测试用例---思路分析

测一四年我在YX公司带测试团队&#xff0c;一个用例评审的会议上&#xff0c;一不小心超常发挥&#xff0c;结果卡在了一个用例设计方法上&#xff0c;印象非常深刻&#xff0c;当时的业务场景是支付方式的选择和优惠方案。 在后来的工作中&#xff0c;也曾几次遇到需要选择合…

Docker 安装

Docker 官网&#xff1a;Docker: Accelerated Container Application Development Docker Hub官网&#xff1a;https://hub.docker.com/ 前提说明 CentOS Docker 安装 前提条件 目前&#xff0c;CentOS 仅发行版本中的内核支持 Docker。Docker 运行在CentOS 7 (64-bit)上&…

软件定制开发具有以下特点|APP搭建|小程序

软件定制开发具有以下特点|APP定制|小程序 一、快速响应用户需求 软件定制开发的优势在于&#xff0c;它可以快速响应用户的需求&#xff0c;因为它是在现有软件的基础上进行功能定制、界面定制、服务定制等改造&#xff0c;而不是从零开始进行重新设计与开发&#xff0c;所以…

vscode快捷键大全中英文

vscode快捷键大全中英文 源文件下载链接

卷运维不如卷网络安全

最近发现很多从事运维的选择了辞职&#xff0c;重新规划自己的职业发展方向。运维工程师这个岗位在IT行业里面确实是处于最底层的&#xff0c;不管什么环节出现问题&#xff0c;基本都是运维背锅。背锅也就罢了&#xff0c;薪资水平也比不上别的岗位。 一般运维的薪资水平大多数…

根据商品ID获得淘宝商品详情, 获得淘宝商品详情高级版,获得淘宝商品评论, 获得淘宝商品快递费用 ,获得淘口令真实,批量获得淘宝商品上下架时间)

参数说明 通用参数说明 参数不要乱传&#xff0c;否则不管成功失败都会扣费url说明 https://api-gw.…….cn/平台/API类型/ 平台&#xff1a;淘宝&#xff0c;京东等&#xff0c; API类型:[item_search,item_get,item_search_shop等]version:API版本key:调用key,测试key:test_…

Google Sign In error 12500

接入Google登录遇到12500报错&#xff0c;网上查到的原因是后台配置包的签名哈希值不正确&#xff0c;但是我们的应用并没有使用firebase管理&#xff0c;尝试多次之后终于找到了解决方法&#xff1a;在开发者后台应用管理界面&#xff0c;创建一个新的凭据【类型为Andorid】&a…

外国电影字幕翻译,怎么把英文字幕翻译成中文字幕?

我们知道&#xff0c;在国内外文化交流中&#xff0c;影视字幕翻译扮演着重要的角色&#xff0c;不仅让观众领略到异国风情&#xff0c;更能达到文化传播的功能。那么&#xff0c;针对外国电影字幕翻译&#xff0c;怎么把英文字幕翻译成中文字幕呢&#xff0c;有什么好的技巧呢…

特斯拉Dojo超算:AI训练平台的自动驾驶与通用人工智能之关键

特斯拉公开Dojo超算架构细节&#xff0c;AI训练算力平台成为其自动驾驶与通用人工智能布局的关键一环 在近日举行的Hot Chips 34会议上&#xff0c;特斯拉披露了其自主研发的AI超算Dojo的详细信息。Dojo是一个可定制的超级计算机&#xff0c;从芯片到系统全部由特斯拉自主设计…

RT Preempt linux学习笔记

RT Preempt linux学习笔记 一、实时操作系统&#xff08;Realtime Operating System&#xff09; 1. 什么是实时操作系统 A real-time system is a time-bound system which has well-defined, fixed time constraints. Processing must be done within the defined constra…

详解Nacos和Eureka的区别

文章目录 Eureka是什么Nacos是什么Nacos的实现原理 Nacos和Eureka的区别CAP理论连接方式服务异常剔除操作实例方式自我保护机制 Eureka是什么 Eureka 是Spring Cloud 微服务框架默认的也是推荐的服务注册中心, 由Netflix公司与2012将其开源出来,Eureka基于REST服务开发,主要用…

Linux安装kafka-manager

相关链接https://github.com/yahoo/kafka-manager/releases kafka-manager-2.0.0.2下载地址 百度云链接&#xff1a;https://pan.baidu.com/s/1XinGcwpXU9YBF46qkrKS_A 提取码&#xff1a;tzvg 一、安装部署 1.把kafka-manager-2.0.0.2.zip拷贝到目录 /opt/app/elk 2.解压…

ctf web基础php

1.preg_match函数绕过 1.数组绕过 <?php $pass$_GET[zx]; if(!preg_match("/admin/",$zx)false){die(hacker); } echo flag; ?> ?zx[]admin 2.换行符绕过 <?php $pass$_GET[zx]; if(!preg_match("/^.(admin).$/",$zx)false){die(hacker)…

自定义权限指令与防止连点指令

1.权限指令 // 注册一个全局自定义权限指令 v-permission Vue.directive(permission, {inserted: function(el, binding, vnode) {const {value} binding; // 指令传的值// user:edit:phone,sysData:sampleconst permissions [user:edit:address, sysData:entrust, sysData:…

vscode编写前端提升效率的三个必不可缺的插件以及使用方法

直接官网下载这个软件就行&#xff0c;没什么操作的。 这里面有新建文件夹&#xff0c;你可以自己去建一个文件夹 然后点击那个小号&#xff0c;就可以新建一个文件&#xff0c;比如说demo01.html,⚠️后面的html是你需要自己手动输入的 第一个插件&#xff0c;就是这个她可以让…

合肥先进光源国家重大科技基础设施项目及配套工程启动会纪念

合肥先进光源国家重大科技基础设施项目及配套工程启动会纪念 卡西莫多 合肥长丰岗集里 肥鸭从此别泥塘 先平场地设围栏 进而工地筑基忙 光阴似箭指日争 源流汇智山水长 国器西北扩新地 家校又添新区园 重器托举有群力 大步穿梭两地间 科教兴邦大国策 技术盈身坦荡行…

arcgis 面要素相交

假设有绿色面图层和紫色面图层&#xff0c;绿色图层有两个区域aa和bb&#xff0c;现在想得到紫色图层分别落在aa和bb上的部分&#xff0c;并附上属性值。 要用到相交功能。 ArcToolbox - Analysis Tools - Overlay - Intersect 输入&#xff1a;把涉及到的两个图层都输入进去…

【前端知识】Three 学习日志(九)—— 阵列立方体和相机适配体验

Three 学习日志&#xff08;九&#xff09;—— 阵列立方体和相机适配体验 一、双层for循环创建阵列模型 //创建一个长方体几何对象Geometry const geometry new THREE.BoxGeometry(100, 100, 100); //材质对象Material const material new THREE.MeshLambertMaterial({col…