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()
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章