Spark SQL大数据分析快速上手-DataFrame应用体验

【图书介绍】《Spark SQL大数据分析快速上手》-CSDN博客

《Spark SQL大数据分析快速上手》【摘要 书评 试读】- 京东图书

大数据与数据分析_夏天又到了的博客-CSDN博客

本节主要介绍如何使用DataFrame进行编程。

4.1.1 SparkSession

在旧版本中,Spark SQL提供两种SQL查询起始点:一个叫作SQLContext,用于Spark自己提供的SQL查询;一个叫作HiveContext,用于连接Hive的查询。

SparkSession是Spark最新的SQL查询起始点,实质上是SQLContext和HiveContext的组合。因此,在SQLContext和HiveContext上可用的API,在SparkSession上同样可以使用。

SparkSession内部封装了SparkContext,所以计算实际上是由SparkContext完成的。

当我们使用Spark Shell的时候,Spark会自动创建一个叫作spark的SparkSession,就像以前可以自动获取一个sc来表示SparkContext一样,如图4-1所示。

图4-1 自动创建SparkSession

4.1.2 DataFrame应用

Spark SQL的DataFrame API允许我们使用DataFrame而不必去注册临时表或者生成SQL表达式。DataFrame API既有转换操作,也有行动操作;DataSet API则提供了更加函数式的API。

1. 创建DataFrame

有了SparkSession之后,可以通过以下3种方式来创建DataFrame:

  • 通过Spark的数据源来创建。
  • 通过已知的RDD来创建。
  • 通过查询一个Hive表来创建。

Spark支持的数据源如图4-2所示。

图4-2 Spark支持的数据源

通过Spark数据源创建DataFrame的代码如下:

复制代码
// 读取 JSON 文件
scala> val df = spark.read.json("/opt/module/spark-local/examples/src/main/ resources/employees.json")
df: org.apache.spark.sql.DataFrame = [name: string, salary: bigint]

// 展示结果
scala> df.show
+-------+------+
|   name|salary|
+-------+------+
|Michael|  3000|
|   Andy|  4500|
| Justin|  3500|
|  Berta|  4000|
+-------+------+

其中,employees.json文件内容如下:

复制代码
{"name":"Michael", "salary":3000}
{"name":"Andy", "salary":4500}
{"name":"Justin", "salary":3500}
{"name":"Berta", "salary":4000}
2. DataFrame语法风格

1)SQL语法风格

SQL语法风格是指我们查询数据的时候可以使用SQL语句。这种SQL语句风格的查询必须有临时视图或者全局视图来辅助。

创建视图的数据来源于people.json,其内容如下:

复制代码
{"name":"Michael"}
{"name":"Andy", "age":30}
{"name":"Justin", "age":19}

创建临时视图的代码如下:

复制代码
scala> val df = spark.read.json("/opt/module/spark-local/examples/ src/main/resources/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]

scala> df.createOrReplaceTempView("people")

scala> spark.sql("select * from people").show
+----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+

创建全局视图的代码如下:

复制代码
scala> val df = spark.read.json("/opt/module/spark-local/examples/src/main/ resources/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]

scala> df.createGlobalTempView("people")

scala> spark.sql("select * from global_temp.people")
res31: org.apache.spark.sql.DataFrame = [age: bigint, name: string]

scala> res31.show
+----+-------+
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+

2)DSL语法风格

DataFrame提供一个特定领域语言(domain-specific language,DSL)去管理结构化的数据。可以在Scala、Java、Python和R中使用DSL。使用DSL语法风格就不必创建临时视图了。

(1)查看schema信息,示例代码如下:

复制代码
scala> val df = spark.read.json("/opt/module/spark-local/examples/src/main/ resources/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]

scala> df.printSchema
root
|-- age: long (nullable = true)
|-- name: string (nullable = true)

(2)使用DSL查询,示例代码如下:

只查询name列数据:

复制代码
scala> df.select($"name").show
+-------+
|   name|
+-------+
|Michael|
|   Andy|
| Justin|
+-------+


scala> df.select("name").show
+-------+
|   name|
+-------+
|Michael|
|   Andy|
| Justin|

查询name和age列数据:

复制代码
scala> df.select("name", "age").show
+-------+----+
|   name| age|
+-------+----+
|Michael|null|
|   Andy|  30|
| Justin|  19|
+-------+----+

查询name和age + 1的数据:

复制代码
scala> df.select($"name", $"age" + 1).show
+-------+---------+
|   name|(age + 1)|
+-------+---------+
|Michael|     null|
|   Andy|       31|
| Justin|       20|
+-------+---------+

查询age大于20的数据:

复制代码
scala> df.filter($"age" > 21).show
+---+----+
|age|name|
+---+----+
| 30|Andy|
+---+----+

按照age分组,查看数据条数:

复制代码
scala> df.groupBy("age").count.show
+----+-----+
| age|count|
+----+-----+
|  19|    1|
|null|    1|
|  30|    1|
+----+-----+
3. RDD和DataFrame的交互

1)从RDD到DataFrame

涉及RDD、DataFrame、DataSet之间的操作时,需要进行导入,即import spark.implicits._。这里的spark不是包名,而是表示SparkSession的那个对象,所以必须先创建SparkSession对象再导入;implicits是一个内部对象。

首先创建一个RDD:

复制代码
scala> val rdd1 = sc.textFile("/opt/module/spark-local/examples/src/main/resources/people.txt")
rdd1: org.apache.spark.rdd.RDD[String] = /opt/module/spark-local/examples/src/main/resources/people.txt MapPartitionsRDD[10] at textFile at <console>:24

然后进行转换,转换有3种方法:手动转换、通过样例类反射转换和通过API的方式转换。

(1)手动转换。

示例代码如下:

复制代码
scala> val rdd2 = rdd1.map(line => { val paras = line.split(", "); (paras(0), paras(1).toInt)})
rdd2: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[11] at map at <console>:26

// 转换为DataFrame的时候手动指定每个数据字段名
scala> rdd2.toDF("name", "age").show
+-------+---+
|   name|age|
+-------+---+
|Michael| 29|
|   Andy| 30|
| Justin| 19|
+-------+---+

(2)通过样例类反射转换。

首先创建样例类:

复制代码
scala> case class People(name :String, age: Int)
defined class People

然后使用样例把 RDD 转换成DataFrame:

复制代码
scala> val rdd2 = rdd1.map(line => { val paras = line.split(", "); People(paras(0), paras(1).toInt) })
rdd2: org.apache.spark.rdd.RDD[People] = MapPartitionsRDD[6] at map at <console>:28

scala> rdd2.toDF.show
+-------+---+
|   name|age|
+-------+---+
|Michael| 29|
|   Andy| 30|
| Justin| 19|
+-------+---+

(3)通过API的方式转换。

通过API方式转换不能在spark命令行下进行,需要编写完整的Scala程序代码,示例代码 如下:

代码4-1 DataFrameDemo.scala

复制代码
import org.apache.spark.SparkContext
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.types.{IntegerType, StringType, StructField, StructType}
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}

object DataFrameDemo {
    def main(args: Array[String]): Unit = {
        val spark: SparkSession = SparkSession.builder()
            .master("local[*]")
            .appName("Word Count")
            .getOrCreate()
        val sc: SparkContext = spark.sparkContext
        val rdd: RDD[(String, Int)] = sc.parallelize(Array(("lisi", 10), ("zs", 20), ("zhiling", 40)))
        // 映射出来一个 RDD[Row], 因为 DataFrame其实就是 DataSet[Row]
        val rowRdd: RDD[Row] = rdd.map(x => Row(x._1, x._2))
        // 创建 StructType 类型
        val types = StructType(Array(StructField("name", StringType), StructField("age", IntegerType)))
        val df: DataFrame = spark.createDataFrame(rowRdd, types)
        df.show

    }
}

2)从DataFrame到RDD

直接调用DataFrame的rdd方法就能完成转换。示例代码如下:

复制代码
scala> val df = spark.read.json("/opt/module/spark-local/examples/src/main/resources/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]

scala> val rdd = df.rdd
rdd: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[6] at rdd at <console>:25

scala> rdd.collect
res0: Array[org.apache.spark.sql.Row] = Array([null,Michael], [30,Andy], [19,Justin])
相关推荐
zhang988000010 小时前
储能领域大数据平台的设计中如何使用 Hadoop、Spark、Flink 等组件实现数据采集、清洗、存储及实时 / 离线计算,支持储能系统分析与预测
大数据·hadoop·spark
数据慢想11 小时前
从2小时到3分钟:Spark SQL多维分析性能优化实战
spark
计算机毕设残哥2 天前
完整技术栈分享:基于Hadoop+Spark的在线教育投融资大数据可视化分析系统
大数据·hadoop·python·信息可视化·spark·计算机毕设·计算机毕业设计
计算机源码社3 天前
分享一个基于Hadoop+spark的超市销售数据分析与可视化系统,超市顾客消费行为分析系统的设计与实现
大数据·hadoop·数据分析·spark·计算机毕业设计源码·计算机毕设选题·大数据选题推荐
码界筑梦坊3 天前
135-基于Spark的抖音数据分析热度预测系统
大数据·python·数据分析·spark·毕业设计·echarts
计算机毕业设计木哥4 天前
计算机毕设大数据选题推荐 基于spark+Hadoop+python的贵州茅台股票数据分析系统【源码+文档+调试】
大数据·hadoop·python·计算机网络·spark·课程设计
请提交用户昵称4 天前
Spark运行架构
大数据·架构·spark
计算机毕业设计木哥4 天前
基于大数据spark的医用消耗选品采集数据可视化分析系统【Hadoop、spark、python】
大数据·hadoop·python·信息可视化·spark·课程设计
卖寂寞的小男孩4 天前
Spark执行计划与UI分析
ui·ajax·spark
计算机毕设-小月哥5 天前
【限时分享:Hadoop+Spark+Vue技术栈电信客服数据分析系统完整实现方案
大数据·vue.js·hadoop·python·信息可视化·spark·计算机毕业设计