DataFrame和RDD之间的区别以及两者之间的相互转换

一、DataFrame和RDD之间的区别
从下面的图中可以看出DataFrame和RDD的区别。RDD是分布式的 Java对象的集合,比如,RDD[Person]是以Person为类型参数,但是,Person类的内部结构对于RDD而言却是不可知的。DataFrame是一种以RDD为基础的分布式数据集,也就是分布式的Row对象的集合(每个Row对象代表一行记录),提供了详细的结构信息,也就是我们经常说的模式(schema),Spark SQL可以清楚地知道该数据集中包含哪些列、每列的名称和类型。
和RDD一样,DataFrame的各种变换操作也采用惰性机制,只是记录了各种转换的逻辑转换路线图(是一个DAG图),不会发生真正的计算,这个DAG图相当于一个逻辑查询计划,最终,会被翻译成物理查询计划,生成RDD DAG,按照之前介绍的RDD DAG的执行方式去完成最终的计算得到结果。
在这里插入图片描述

二、DataFrame和RDD之间的相互转化
RDD转为DataFrame

1、方式一,通过反射方式,代码相对简单,使用反射推断来包含 特定数据的类型的RDD的元数据
步骤:
(1)创建SparkCOntext,在创建SQLContext
(2)先用sc创建RDD,对数据进行处理,然后关联case class,将非结构化的数据转换成结构化数据
(3)(使用隐式转换)显示的调用toDF方法,将RDD装换成DataFrame
(4)注册临时表
(5)执行SQL(Transformation,lazy)
(6)执行Action(show方法)

import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{Row, SparkSession}

object SQLCaseDemo {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().appName("sql").master("local").getOrCreate()
    val data : RDD[String] = spark.sparkContext.textFile("D://stu.txt")
    
    //对读取到的数据进行处理,使RDD中的类型是一个样例类
    val peopRDD: RDD[peopleSQL] = data.map(m => {
      val sp : Array[String] = m.split(" ")
      peopleSQL(sp(0), sp(1).toInt)
    })
    //导入隐式转换
    import spark.implicits._
    //转换成DataFrame
    val df1 : DataFrame = peopRDD.toDF("name","age")
    df1.createTempView("people_t")
    //可以用SQL语句对注册的表进行操作
    val df2 : DataFrame = spark.sql("select * from people_t")
   //将结果展示出来, show 是Action方法
    df2.show()
  }
}
//样例类
case class peopleSQL(name:String, age :Int)

对于这种方式,有一个简单的方法,可以不用使用样例类,直接使用元组,一样可以转换成DataFrame

import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{Row, SparkSession}

object SQLCaseDemo {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().appName("sql").master("local").getOrCreate()
    val data : RDD[String] = spark.sparkContext.textFile("D://stu.txt")
    
    //使用元组
    val peopRDD: RDD[(String,Int)] = data.map(m => {
      val sp : Array[String] = m.split(" ")
      (sp(0), sp(1).toInt)
    })
    //导入隐式转换,这里的spark是第一行创建的spark
    import spark.implicits._
    //转换成DataFrame
    val df1 : DataFrame = peopRDD.toDF("name","age")
    df1.createTempView("people_t")
    //可以用SQL语句对注册的表进行操作
    val df2 : DataFrame = spark.sql("select * from people_t")
   //将结果展示出来, show 是Action方法
    df2.show()
  }
}

2、方式二
通过编程接口的方式,你可以自己动态构建一根元数据,这种方式代码较多,适合不知道元数据的时候时候,一般都是使用这种
1、创建sparkContext,然后再创建SQLContext
2、先用sc创建RDD,对数据进行处理,然后关联Row,,将非结构化的数据转化为结构化数据
3、显示的调用sqlContext的CreateDataFrame方法方法,将RDD装换成DataFrame(import )
4、注册临时表
5、执行SQL(Transformation,lazy)
6、执行Action(show方法)

object SQLandCore {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().appName("demo").master("local").getOrCreate()
    val lines = spark.sparkContext.textFile("C:\\data.txt")
 

    val rowRDD: RDD[Row] = lines.map(m => {
      val sp : Array[String] = m.split(" ")
      //使用Row类型的对数据进行包装
      Row(sp(0), sp(1).toDouble)
    })
//根据Row中的类型为数据创建相应的元数据
    val structType = types.StructType(List(new StructField("phoneNum",StringType,true),new StructField("money",DoubleType,true)))
    //把rdd转成DataFrame
    val df = spark.createDataFrame(rowRDD,structType)
    //注册临时视图,也就是表,然后就可以当成一张表使用了,可以进行一系列sql操作
    df.createTempView("data")
    val df2 : DataFream = spark.sql("select * from stu where money > 60")
    df2.show()
    spark.close()

  }

}

DataFrame转成RDD

object SQLandCore {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().appName("demo").master("local").getOrCreate()
    val lines = spark.sparkContext.textFile("C:\\data.txt")
 

    val rowRDD: RDD[Row] = lines.map(m => {
      val sp : Array[String] = m.split(" ")
      //使用Row类型的对数据进行包装
      Row(sp(0), sp(1).toDouble)
    })
//根据Row中的类型为数据创建相应的元数据
    val structType = types.StructType(List(new StructField("phoneNum",StringType,true),new StructField("money",DoubleType,true)))
    //把rdd转成DataFrame
    val df = spark.createDataFrame(rowRDD,structType)
    //注册临时视图,也就是表,然后就可以当成一张表使用了,可以进行一系列sql操作
    df.createTempView("data")
    val df2 : DataFream = spark.sql("select * from stu where money > 60")
    ======================================================================
    //以上都是前面写过的代码,下面把DataFrame转成RDD
	//通过.rdd 把DataFrame转成 RDD[Row]类型
	val rdd1: RDD[Row] = df2.rdd
	//在转成普通的rdd
	val rdd2 : (String,Double) = rdd1.map(m=>{
		val phoneNum = m.getString(0)
		val money = m.getDouble(1)
		(phoneNum,money)
	})
    
    spark.close()

  }

}

猜你喜欢

转载自blog.csdn.net/Lu_Xiao_Yue/article/details/84191127
今日推荐