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()
}
}