Spark:DataFrame如何成为Dataset [Row],如果DataFrame具有模式(schema)?

7

这篇文章声称在Spark中,DataFrame等价于Dataset[Row],但是这篇博客文章表明DataFrame有一个模式(schema)。

以该博客文章中将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个回答

10

在Spark 2.0中,代码中有:

type DataFrame = Dataset[Row]

这是因为定义而得到的 Dataset[Row]

Dataset也有模式(schema),您可以使用printSchema()函数打印它。通常情况下,Spark会自动推断出模式,所以您不必手动编写 - 然而它仍然存在😉

您还可以执行createTempView(name)并像DataFrames一样在SQL查询中使用它。

换句话说,Dataset = Spark 1.5的DataFrame + 编码器,它将行转换为您的类。在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)

2
注意(除了 T Gaweda 的答案之外),每个 Row 都有一个关联的模式(Row.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))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接