RDD转换成DataFrame的两种方式
一、概述
Spark SQL支持两种不同的方式将RDD转换为DataFrame。第一种是使用反射来推断包含特定类型对象的RDD的模式,这种基于反射的方式可以提供更简洁的代码,如果在编写Spark应用程序时,已经明确了schema,可以使用这种方式。第二种方式是通过可编程接口来构建schema,然后将其应用于现有的RDD。此方式编写的代码更冗长,但在不知道colum及其type的情况下,可以使用这种方式。
Michael, 29
Andy, 30
Justin, 19
二、RDD转DataFrame案例
1.通过反射的方式
Spark SQL的Scala接口支持自动将包含样例类的RDD转换为DataFrame。样例类定义表的schema。通过反射读取样例类的参数名称,并映射成column的名称。
package com.company.sparksql
import org.apache.log4j.{Level, Logger}
import org.apache.spark.sql.SparkSession
object RDD2DF_m1 {
//创建样例类
case class Person(name: String, age: Int)
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("RDD2DF_m1")
.master("local")
.getOrCreate()
Logger.getLogger("org.apache.spark").setLevel(Level.OFF)
Logger.getLogger("org.apache.hadoop").setLevel(Level.OFF)
runRDD2DF(spark)
}
private def runRDD2DF(spark: SparkSession) = {
//导入隐式转换,用于RDD转为DataFrame
import spark.implicits._
//从文本文件中创建RDD,并将其转换为DataFrame
val peopleDF = spark.sparkContext
.textFile("file:///E:/people.txt")
.map(_.split(","))
.map(attributes => Person(attributes(0), attributes(1).trim.toInt))
.toDF()
//将DataFrame注册成临时视图
peopleDF.createOrReplaceTempView("people")
// 运行SQL语句
val teenagersDF = spark.sql("SELECT name, age FROM people WHERE age BETWEEN 13 AND 19")
// 使用字段索引访问列
teenagersDF.map(teenager => "Name: " + teenager(0)).show()
// +------------+
// | value|
// +------------+
// |Name: Justin|
// +------------+
// 通过字段名访问列
teenagersDF.map(teenager => "Name: " + teenager.getAs[String]("name")).show()
// +------------+
// | value|
// +------------+
// |Name: Justin|
// +------------+
}
}
2.通过构建schema的方式
通过构建schema的方式创建DataFrame主要包括三步:
(1)从原始RDD创建Row类型的RDD
(2)使用StructType,创建schema
(3)通过createDataFrame方法将schema应用于Row类型的RDD
package com.company.sparksql
import org.apache.log4j.{Level, Logger}
import org.apache.spark.sql.types.{IntegerType, StringType, StructField, StructType}
import org.apache.spark.sql.{Row, SparkSession}
object RDD2DF_m2 {
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("RDD2DF_m1")
.master("local")
.getOrCreate()
Logger.getLogger("org.apache.spark").setLevel(Level.OFF)
Logger.getLogger("org.apache.hadoop").setLevel(Level.OFF)
runRDD2DF(spark)
}
private def runRDD2DF(spark: SparkSession) = {
//导入隐式转换,用于RDD转为DataFrame
import spark.implicits._
//创建原始RDD
val peopleRDD = spark.sparkContext.textFile("file:///E:/people.txt")
//step 1 将原始RDD转换为ROW类型的RDD
val rowRDD = peopleRDD
.map(_.split(","))
.map(attributes => Row(attributes(0), attributes(1).trim.toInt))
//step 2 创建schema
val schema = StructType(Array(
StructField("name", StringType, true),
StructField("age", IntegerType, true)
))
//step 3 创建DF
val peopleDF = spark.createDataFrame(rowRDD, schema)
// 将DataFrame注册成临时视图
peopleDF.createOrReplaceTempView("people")
// 运行SQL语句
val results = spark.sql("SELECT name FROM people")
// 使用字段索引访问列
results.map(attributes => "Name: " + attributes(0)).show()
// +-------------+
// | value|
// +-------------+
// |Name: Michael|
// | Name: Andy|
// | Name: Justin|
// +-------------+
}
}
公众号「大数据技术与数仓」
专注分享数据仓库与大数据技术