DataFrame与RDD的互操作
1.Spark SQL支持将现有的RDDs转换为数据集的两种不同的方法。第一个方法使用反射来推断一个包含特定对象类型的RDD的模式。这种基于反射的方法会导致更简洁的代码,但要在编写Spark应用程序时就已经知道了Schema。
2.创建数据集的第二种方法是通过一个编程接口,它允许您构造一个模式,然后将其应用到现有的RDD中。虽然这个方法比较冗长,但是它在运行时构造数据集并且它们的类型直到运行时才知道。
(一)反射方式Spark SQL的Scala接口支持自动将包含case类的RDD转换为DataFrame。 case类定义了表的Schema。 对case类的参数的名称是使用反射读取的,并成为列的名称。 Case类也可以嵌套或包含复杂的类型,例如Seqs或数组。 这个RDD可以隐式地转换为一个DataFrame,然后将其注册为一个表。 表可以在后续的SQL语句中使用。
import org.apache.log4j.{Level, Logger}
import org.apache.spark.sql.SparkSession
/**
* Created by **** 2017/12/23 10:47
* DataFrame和RDD的互操作
* (一)方式方式:使用反射来推断包含了特定数据类型的RDD的元数据(case class)
* 使用DataFrame API或者sql方式编程
*/
object DataFrameRDDApp {
def main(args: Array[String]): Unit = {
SetLogger()
val spark = SparkSession.builder()
.master("local[2]")
.appName("DataFrameRDDApp").getOrCreate()
//RDD ==> DataFrame
val peopleRDD = spark.sparkContext.textFile("src/data/people.txt")
// 注意:需要导入隐式转换 RDD.toDF ==> DataFrame
import spark.implicits._
val peopleDF = peopleRDD.map(_.split(","))
.map(line =>
People(line(0).toInt,line(1),line(2).toInt)
).toDF()
peopleDF.printSchema()
peopleDF.show()
// 使用DataFrame API编程
peopleDF.filter(peopleDF.col("age")>30).show()
//使用SQL方式编程,要先创建临时表
peopleDF.createOrReplaceTempView("people")
spark.sql("select * from people where age > 30").show()
spark.stop()
}
case class People(id: Int, name: String, age: Int)
def SetLogger() = {
Logger.getLogger("org").setLevel(Level.OFF)
Logger.getLogger("com").setLevel(Level.OFF)
System.setProperty("spark.ui.showConsoleProgress", "false")
Logger.getRootLogger().setLevel(Level.OFF);
}
}
(二) 以编程方式指定模式
当case类不能提前定义时(例如,记录的结构是在一个字符串中编码的,或者文本数据集将被解析,不同的用户将对字段进行不同的预测),一个DataFrame可以用3个步骤来创建。
- 从原始的RDD中创建一个行;
- 创建在第1步中创建的RDD中所表示的结构类型的结构类型。Create the schema represented by a
StructType
matching the structure ofRow
s in the RDD created in Step 1. - 通过SparkSession提供的createDataFrame方法将模式应用到行的RDD中。
val peopleRDD = spark.sparkContext.textFile("src/data/people.txt")
val rowRDD = peopleRDD.map(_.split(",")).map(line =>
Row(line(0).toInt, line(1), line(2).toInt)
)
val structType = StructType(
Array(
StructField("id",IntegerType,true),
StructField("name",StringType,true),
StructField("age",IntegerType,true)
))
val peopleDF = spark.createDataFrame(rowRDD,structType)
peopleDF.printSchema()
peopleDF.show()