Spark SQL 之 DataFrame
文章目录
1. 创建 DataFrame
1.1 通过 Spark
的数据源创建
Spark
支持的数据源
-
示例:
scala> val df = spark.read.json("./stu.json") df: org.apache.spark.sql.DataFrame = [age: bigint, name: string] scala> df.show +---+----+ |age|name| +---+----+ | 22| zgl| | 18| zzx| | 20| zzz| +---+----+
1.2 通过已知的 RDD
来创建
1.3 通过查询一个 Hive
表来创建
2. DataFrame 语法风格
2.1 SQL 语法风格
-
SQL
语法风格是指查询数据时使用SQL
语句来查询。 -
这种风格的查询必须要有临时视图或者全局视图来辅助。
scala> val df = spark.read.json("./stu.json") df: org.apache.spark.sql.DataFrame = [age: bigint, name: string] scala> df.createOrReplaceTempView("student") scala> spark.sql("select * from student").show +---+----+ |age|name| +---+----+ | 22| zgl| | 18| zzx| | 20| zzz| +---+----+
-
临时视图只能在当前
Session
有效,在新的Session
中无效。 -
可以创建全局视图,访问全局视图需要全路径:如,
global_temp.xxx
。scala> val df = spark.read.json("./stu.json") df: org.apache.spark.sql.DataFrame = [age: bigint, name: string] scala> df.createGlobalTempView("student") scala> spark.sql("select * from global_temp.student").show +---+----+ |age|name| +---+----+ | 22| zgl| | 18| zzx| | 20| zzz| +---+----+ scala> spark.newSession.sql("select name, age from global_temp.student").show +----+---+ |name|age| +----+---+ | zgl| 22| | zzx| 18| | zzz| 20| +----+---+
2.2 DSL 语法风格
-
DataFrame
提供一个特定领域语言(DSL)
去管理结构化的数据,可以在Scala、Java、Python、R
中使用。 -
使用
DSL
语法分格就不需要创建临时视图了。 -
使用
DSL
查询// 只查询 name 列数据 scala> df.select($"name").show +----+ |name| +----+ | zgl| | zzx| | zzz| +----+ scala> df.select("name").show +----+ |name| +----+ | zgl| | zzx| | zzz| +----+ // 查询 name 和 age scala> df.select("name","age").show +----+---+ |name|age| +----+---+ | zgl| 22| | zzx| 18| | zzz| 20| +----+---+ // 查询 name 和 age + 1 注意:涉及到运算的收,每列都必使用 $ scala> df.select($"name",$"age"+1).show +----+---------+ |name|(age + 1)| +----+---------+ | zgl| 23| | zzx| 19| | zzz| 21| +----+---------+ // 查询 age ⼤于 20 的数据 scala> df.filter($"age">20).show +---+----+ |age|name| +---+----+ | 22| zgl| +---+----+ // 按照 age 分组,查看数据条数 scala> df.groupBy("age").count.show +---+-----+ |age|count| +---+-----+ | 22| 1| | 18| 1| | 20| 1| +---+-----+
2.3 RDD 和 DataFrame 的交互
2.3.1 从 RDD
到 DataFrame
-
涉及到
RDD , DataFrame , DataSet
之间的操作时, 需要导⼊:import spark.implicits._
这⾥的spark
不是包名, ⽽是表示SparkSession
的那个对象. 所以必须先创建SparkSession
对象再导⼊。implicits
是⼀个内部object
。 -
手动转换:
scala> val rdd = sc.textFile("./stu.txt").map(line=>{val paras=line.split(","); (paras(0),paras(1).toInt)}) rdd: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[83] at map at <console>:24 scala> var df = rdd.toDF("name","age") df: org.apache.spark.sql.DataFrame = [name: string, age: int] scala> df.show +----+---+ |name|age| +----+---+ | zgl| 23| | zzx| 20| | zzz| 18| +----+---+
-
通过样例类反射转换:
// 1.创建样例类 scala> case class Student(name: String, age: Int) defined class Student // 2.使用样例类把 RDD 转换成 DataFrame scala> val rdd = sc.textFile("./stu.txt").map(line=>{val paras=line.split(","); Student(paras(0),paras(1).toInt)}) rdd: org.apache.spark.rdd.RDD[Student] = MapPartitionsRDD[95] at map at <console>:26 scala> var df = rdd.toDF df: org.apache.spark.sql.DataFrame = [name: string, age: int] scala> df.show +----+---+ |name|age| +----+---+ | zgl| 23| | zzx| 20| | zzz| 18| +----+---+
2.3.2 从 DataFrame 到 RDD
-
直接调用
DataFrame
的rdd
方法即可。scala> val df = spark.read.json("./stu.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[112] at rdd at <console>:25 scala> rdd.collect res36: Array[org.apache.spark.sql.Row] = Array([22,zgl], [18,zzx], [20,zzz])