首页 文章

Spark:如果DataFrame有架构,DataFrame如何成为Dataset [Row]

提问于
浏览
1

This article声称Spark中的 DataFrame 等同于 Dataset[Row] ,但this blog post表明 DataFrame 具有架构 .

以博客文章中的示例为例,将RDD转换为 DataFrame :如果 DataFrameDataset[Row] 相同,那么将 RDD 转换为 DataFrame 就应该如此简单

val rddToDF = rdd.map(value => Row(value))

但相反它表明就是这样

val rddStringToRowRDD = rdd.map(value => Row(value))
val dfschema = StructType(Array(StructField("value",StringType)))
val rddToDF = sparkSession.createDataFrame(rddStringToRowRDD,dfschema)
val rDDToDataSet = rddToDF.as[String]

显然,数据框实际上是行和模式的数据集 .

2 回答

  • 1

    在Spark 2.0中,在代码中有: type DataFrame = Dataset[Row]

    它只是因为定义而 Dataset[Row] .

    Dataset 也有架构,你可以使用 printSchema() 函数打印它 . 通常情况下Spark会推断架构,所以你仍然不会在那里;)

    您也可以执行 createTempView(name) 并在SQL查询中使用它,就像DataFrames一样 .

    换句话说, Dataset = DataFrame from Spark 1.5 + encoder 将行转换为您的类 . 在Spark 2.0中合并类型后,DataFrame只是 Dataset[Row] 的别名,因此没有指定编码器 .

    关于转换:rdd.map()也返回 RDD ,它永远不会返回DataFrame . 你可以做:

    # Dataset[Row]=DataFrame, without encoder
    val rddToDF = sparkSession.createDataFrame(rdd)
    # And now it has information, that encoder for String should be used - so it becomes Dataset[String]
    val rDDToDataSet = rddToDF.as[String]
    
    # however, it can be shortened to:
    val dataset = sparkSession.createDataset(rdd)
    
  • 1

    注意(除了T Gaweda的答案),每个 RowRow.schema )都有一个模式 . 但是,在将该模式集成到 DataFrame (或 Dataset[Row] )之前,不会设置此模式

    scala> Row(1).schema
    res12: org.apache.spark.sql.types.StructType = null
    
    scala> val rdd = sc.parallelize(List(Row(1)))
    rdd: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = ParallelCollectionRDD[5] at parallelize at <console>:28
    scala> spark.createDataFrame(rdd,schema).first
    res15: org.apache.spark.sql.Row = [1]
    scala> spark.createDataFrame(rdd,schema).first.schema
    res16: org.apache.spark.sql.types.StructType = StructType(StructField(a,IntegerType,true))
    

相关问题