Spark RDD轉換成DataFrame的兩種方式

Spark SQL支持兩種方式將現有RDD轉換爲DataFrame。
第一種方法使用反射來推斷RDD的schema並創建DataSet然後將其轉化爲DataFrame。這種基於反射方法十分簡便,但是前提是在您編寫Spark應用程序時就已經知道RDD的schema類型。
第二種方法是通過編程接口,使用您構建的StructType,然後將其應用於現有RDD。雖然此方法很麻煩,但它允許您在運行之前並不知道列及其類型的情況下構建DataSet

    方法如下
         1.將RDD轉換成Rows   
         2.按照第一步Rows的結構定義StructType  
         3.基於rows和StructType使用createDataFrame創建相應的DF

測試數據爲order.data

1   小王  電視  12  2015-08-01 09:08:31
1   小王  冰箱  24  2015-08-01 09:08:14
2   小李  空調  12  2015-09-02 09:01:31

代碼如下:

object RDD2DF {

  /**
    * 主要有兩種方式
    *   第一種是在已經知道schema已經知道的情況下,我們使用反射把RDD轉換成DS,進而轉換成DF
    *   第二種是你不能提前定義好case class,例如數據的結構是以String類型存在的。我們使用接口自定義一個schema
    * @param args
    */
  def main(args: Array[String]): Unit = {

    val spark=SparkSession.builder()
      .appName("DFDemo")
      .master("local[2]")
      .getOrCreate()

//    rdd2DFFunc1(spark)

    rdd2DFFunc2(spark)
    spark.stop()
  }

  /**
    * 提前定義好case class
    * @param spark
    */
  def rdd2DFFunc1(spark:SparkSession): Unit ={
    import spark.implicits._
    val orderRDD=spark.sparkContext.textFile("F:\\JAVA\\WorkSpace\\spark\\src\\main\\resources\\order.data")
    val orderDF=orderRDD.map(_.split("\t"))
      .map(attributes=>Order(attributes(0),attributes(1),attributes(2),attributes(3),attributes(4)))
      .toDF()
    orderDF.show()
    Thread.sleep(1000000)
  }

  /**
    *總結:第二種方式就是通過最基礎的DF接口方法,將
    * @param spark
    */
  def rdd2DFFunc2(spark:SparkSession): Unit ={
    //TODO:   1.將RDD轉換成Rows   2.按照第一步Rows的結構定義StructType  3.基於rows和StructType使用createDataFrame創建相應的DF
    val orderRDD=spark.sparkContext.textFile("F:\\JAVA\\WorkSpace\\spark\\src\\main\\resources\\order.data")

    //TODO:   1.將RDD轉換成Rows
    val rowsRDD=orderRDD
//      .filter((str:String)=>{val arr=str.split("\t");val res=arr(1)!="小李";res})
      .map(_.split("\t"))
      .map(attributes=>Row(attributes(0).trim,attributes(1),attributes(2),attributes(3).trim,attributes(4)))

    //TODO:   2.按照第一步Rows的結構定義StructType
    val schemaString="id|name|commodity|age|date"
    val fields=schemaString.split("\\|")
      .map(filedName=>StructField(filedName,StringType,nullable = true))
    val schema=StructType(fields)

    //TODO:   3.基於rows和StructType使用createDataFrame創建相應的DF
   val orderDF= spark.createDataFrame(rowsRDD,schema)
    orderDF.show()
    orderDF.groupBy("name").count().show()
    orderDF.select("name","commodity").show()
    Thread.sleep(10000000)
  }
}
case class Order(id:String,name:String,commodity:String,age:String,date:String)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章