概述
RDD相比于DataFrame少了数据的结构信息,RDD不知道存储的每一行数内部的结构,而DataFrame却是知道的,所以RDD+schema信息=DataFrame
要将RDD转化为DataFrame有两种方式:
- 使用反射机制推理出schema信息
- 由开发者手动指定schema信息
使用反射机制推理出schema信息
这种方式一般要求被转化的RDD[T]中所包含的T对象本身就是具有典型一维表严格的字段结构对象,因此可以容易推断出schema信息。spark支持包含样例类(case case)对象的RDD转化为DataFrame,样例类不仅包含int、String等简单的数据类型,也可以嵌套或者是包含复杂类型,例如Seq、Array等
以下示例将展示如何将包含person样例类的RDD转化为dataFrame
package sparksql
import org.apache.spark.sql.SparkSession
object SparkSqltest1 {
case class Person(id:Int,name:String,age:Int,money:Long)
def main(args: Array[String]): Unit = {
//创建sparksession
val sparkSession=SparkSession.builder().appName("test1").master("local[*]")getOrCreate()
import sparkSession.implicits._
//读取文件形成dataframe
val rdd=sparkSession.sparkContext.textFile("hdfs://192.168.1.181:9000/test/person.txt")
val person=rdd.map(x=>x.split(",")).map(x=>{
Person(x(0).trim.toInt,x(1),x(2).trim.toInt,x(2).trim.toLong)
})
val df=person.toDF()
df.createTempView("person")
sparkSession.sql("select * from person").show()
rdd.collect()
}
}
程序运行结果为:
+---+--------+---+-----+
| id| name|age|money|
+---+--------+---+-----+
| 1|zhangsan| 12| 12|
| 2| lihua| 11| 11|
| 4| laowu| 34| 34|
+---+--------+---+-----+
开发者指定schema信息
分为三个步骤完成
- 根据需求从源RDD转化成RDD of Rows
- 创建符合Row结果的schema
- 通过create方法将schema应用到RDD
package sparksql
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.{DataFrame, Dataset, Row, SQLContext}
import org.apache.spark.sql.types.{StructField, _}
object SparkSqltest1 {
def main(args: Array[String]): Unit = {
//创建sparksession
val sparkSession=SparkSession.builder().appName("test1").master("local[*]")getOrCreate()
import sparkSession.implicits._
//读取文件形成dataframe
val rdd=sparkSession.sparkContext.textFile("hdfs://192.168.1.181:9000/test/person.txt")
//创建ROW
val rowRdd=rdd.map(x=>x.split(",")).map(attrs=>Row(attrs(0).trim.toInt,attrs(1),attrs(2).trim.toDouble,attrs(3).trim.toDouble))
//创建schema信息
val schema=StructType(List(
StructField("id",IntegerType,true),
StructField("name",StringType,true),
StructField("age",DoubleType,true),
StructField("money",DoubleType,true)
))
//创建dataFrame
val df=sparkSession.createDataFrame(rowRdd,schema);
df.createTempView("person")
sparkSession.sql("select * from person").show()
}
}
运行的结果为:
+---+--------+----+-----+
| id| name| age|money|
+---+--------+----+-----+
| 1|zhangsan|12.0| 13.0|
| 2| lihua|11.0|78.21|
| 4| laowu|34.0| 79.0|
+---+--------+----+-----+
相比而言,第二种方式更为灵活