Spark学习笔记五(Spark SQL,DataFrame和Dataset)

本文介绍了Spark中的DataFrame和Dataset,Dataset是1.6版本引入的强类型数据集合,而DataFrame是无类型的,类似于传统数据库中的表。DataFrame适合处理结构化数据,可以从多种数据源构建。Spark SQL则提供了SQL查询的接口,简化了操作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Spark的早期版本中只有RDD,DataFrame和Dataset都是后续版本中引入的。

一,什么是Dataset

Dataset是在Spark 1.6中引入的新概念。Dataset和RDD类似,是分布式的数据集合,但其中存储的数据可以是typed或untyped。例如下面的json,表达一条IoT数据:

{“device_id”: 198164, “device_name”: “sensor-pad-198164owomcJZ”, “ip”: “80.55.20.25”, “cca2”: “PL”, “cca3”: “POL”, “cn”: “Poland”, “latitude”: 53.080000, “longitude”: 18.620000, “scale”: “Celsius”, “temp”: 21, “humidity”: 65, “battery_level”: 8, “c02_level”: 1408, “lcd”: “red”, “timestamp” :1458081226051}

我们可以在Scala中定义一个类:

case class DeviceIoTData (battery_level: Long, c02_level: Long, cca2: String, cca3: String, cn: String, device_id: Long, device_name: String, humidity: Long, ip: String, latitude: Double, lcd: String, longitude: Double, scale:String, temp: Long, timestamp: Long)

然后我们可以读入json文件,同时使用上面定义的class

val ds = spark.read.json(/databricks-public-datasets/data/iot/iot_devices.json”).as[DeviceIoTData]

在上例中,我们就使用了typed Dataset,且typed Dataset中的一行,就对应了一个DeviceIoTData对象。因此我们说typed Dataset是强类型的。

目前Datasets API只在Scala和Java中支持,Python不支持。原因是Python语言中没有强类型检查,这和Dataset的概念不符合,因此无法实现强类型的Dataset。

下例使用SparkSession,读取csv文件并构建一个Dataset:

scala> val lines = spark.read.textFile("/home/markey/Desktop/Temp/hexindai_batch1-7.csv")
lines: org.apache.spark.sql.Dataset[String] = [value: string]
scala> lines.createTempView(“datasetex”)
scala> spark.sql(“SELECT * FROM datasetex”).show

这个例子与第一个例子的区别是:在Dataset中我们并没有明确每个字段的类型,其结果是每一行实际上是一个String对象。

二,什么是DataFrame

DataFrame is a untyped Dataset organized into named columns。因此DataFrame表现为行和列的组织形式,且不是强类型的,也就是说最终在JVM运行时,DataFrame中的数据的具体类型可以是Spark自己推演出来的,而不像Dataset那样明确。

DataFrame中的每个列对应一个列名和一个类型。可以说DataFrame对应传统数据库中的表,同时和Pandas(Python中常用的一个第三方数据处理类库)中的DataFrame非常类似。因此,DataFrame非常适合用来处理结构化或半结构化数据。但在Spark SQL中,使用Datasets有更高的性能优势,因为Datasets针对Spark SQL进行了性能优化。
我们可以从多种数据源构建DataFrame,包括:Apache Hive表,已存在的Spark RDD以及多种外部数据源(Parquet file,JSON file,支持JDBC的各类数据库等等)。

下例使用SparkSession读入一个csv文件并构建DataFrame:

scala> val hxdDF = spark.read.format(“csv”).option(“sep”, “,”).option(“inferSchema”, “true”).option(“header”, “true”).load("/home/markey/Desktop/Temp/hexindai_batch1-7.csv")
此方法返回一个DataFrame对象,随后我们可以用printSchema()方法查看。

构建好DataFrame后,我们可以用Spark SQL对数据进行各种查询:

scala> hxdDF.createTempView(“hexindai”) – 我们首先要基于DataFrame建立一个view,名为hexindai。可以使用几种不同类型的view,这里不详述。
scala> spark.sql(“SELECT * FROM hexindai”).show – 然后就可以对hexindai进行各种SQL查询了。

其他一些DataFrame常用方法:

scala> df = spark.read.json(“examples/src/main/resources/people.json”)
scala> df.show()
| age| name|
±—±------+
|null|Michael|
| 30| Andy|
| 19| Justin|
±—±------+
scala> df.printSchema() – df是DataFrame因此可以打印schema
root
|-- age: long (nullable = true)
|-- name: string (nullable = true)
–这里我们并没有自定义每个列的数据类型,但DataFrame自动识别了其类型。注意这里的数据类型和前文中的untyped Datasets不是一回事儿。
scala> df.describe(‘age’).show() – describe方法计算DataFrame中数字型字段的数据统计信息。
scala> df.filter(df[‘age’] > 21).show()

有一篇文章非常不错,推荐:
Complete Guide on DataFrame Operations in PySpark

三,什么是Spark SQL
上文中我们已经使用了Spark SQL,简单的说Spark SQL引擎把SQL语句转换为对DataFrame和Dataset的一系列操作,然后又将这些操作转换为更底层的RDD的一系列的transformations和actions。通过使用Spark SQL,我们就不用定义RDD并一步步操作,而是用SQL来高效完成工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值