Spark彈性數據集之間的轉換

Spark彈性數據集之間的轉換

基本轉換小結

RDD -> DataFrame:
可以直接toDF 簡單實現, 複雜結構是 構建RDD[Row] + StructType 實現

DataFrame -> RDD:
df.rdd 實現

DataFrame -> Dataset:
Dataset是強類型的DataFrame, 所以只需要 df.as[case class] 即可, 注意字段類型匹配

Dataset -> DataFrame:

df.toDF 即可

Dataset -> RDD:
DataFrame 使用 df.rdd 實現, 本身 DataFrame 是 Dataset[Row]
所以Dataset 也是 ds.rdd 實現轉換

RDD -> Dataset:
Dataset 是強類型的所以這個地方要求RDD本身就存的是帶有類型的數據(如RDD[case class]) ,使用rdd.toDS 即可完成轉換.

試驗代碼

case class Person(name: String, age: Int)

object Convert {
   
   
    def main(args: Array[String]): Unit = {
   
   
        // 三種基本的彈性數據集合之間的轉換.
        val sparkConf: SparkConf = new SparkConf()
            .setAppName("Type Convert")
            .setMaster("local")

        val sparkSession: SparkSession = SparkSession.builder()
            .config(sparkConf).getOrCreate()

        import sparkSession.implicits._
        val sparkContext = sparkSession.sparkContext

        //構建Rdd
        val rdd1: RDD[Int] = sparkContext.makeRDD(List(1,2,3))
        // 需要引入隱式變化 不然無法調用
        print("RDD 2 DF")
        // 沒有指定列明的時候是value
        val df1: DataFrame = rdd1.toDF("intvalue")
        df1.printSchema()
        df1.show()

        print("df 2 rdd")
        // df 2 rdd 結果是RDD[Row]
        //val rdd2: RDD[Row] = df1.rdd

        // 從RDD 到 DF 可以直接 使用Seq.toDF 得到
        val df2: DataFrame = Seq(1,2,3).toDF("intvalue")
        df2.printSchema()
        df2.show()

        //從 df 到 ds 需要提供強類型 使用as 轉換 注意字段類型問題
        // 如果df是從外部文件構建 整數 schema可能是bigint 所以需要將列轉換一下類型. 和定義的樣例類字段類型對應
        // 複雜類型RDD到 df 之前其實是一列數據RDD到df 如果本身就是比較複雜的數據呢 需要使用 structType

        val rdd3 =  sparkContext.makeRDD(Seq(("a", 10), ("b", 20)))
            .map(item => Row(item._1, item._2))

        // 建立schema DF  需要
        val dataSchema = StructType(List(StructField("name", StringType, nullable = true), StructField("age", IntegerType, nullable = true)))
        // 複雜類型可能 rdd.toDF 無法實現 那麼就老老實實 使用createDF + schema(StructType 和 StructField)實現
        val df3: DataFrame = sparkSession.createDataFrame(rdd3, dataSchema)
        print("內存中創建df 注意數值型 是 integer")
        df3.printSchema()
        df3.show()

        print("DF 轉換成 DS")
        // DS 是強類型的 所以需要 as[定義樣例類型] 完成轉換.
        val ds1: Dataset[Person] = df3.as[Person]
        ds1.printSchema()

        print("DS 轉換回 DF")
        val df4: DataFrame = ds1.toDF()
        df4.printSchema()

        print("DS 轉回 RDD")
        // 直接rdd 因爲DS 是一般的 DataFrame 所以轉回Rdd 直接.rdd
        val rdd4: RDD[Person] = ds1.rdd

        print("rdd 轉 DS")
        // 需要樣例類型信息 而不是rdd 到DF 先構建Row Rdd 再添加 schema完成
        val rdd5: RDD[Person] = sparkContext.makeRDD(Seq(Person("a", 10), Person("b", 20)))

        val ds2: Dataset[Person] = rdd5.toDS()
        ds2.printSchema()

       sparkSession.close()
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章