Spark:如果 DataFrame 有模式,DataFrame 如何成为 Dataset[Row]
Spark: How can DataFrame be Dataset[Row] if DataFrame's have a schema
This article claims that a DataFrame
in Spark is equivalent to a Dataset[Row]
, but this blog post 表明 DataFrame
有一个架构。
以博客 post 中将 RDD 转换为 DataFrame
为例:如果 DataFrame
与 Dataset[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]
显然,数据框实际上是行 和模式 的数据集。
在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() 也 returns RDD
,它从不 returns 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)
请注意(除了 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))
This article claims that a DataFrame
in Spark is equivalent to a Dataset[Row]
, but this blog post 表明 DataFrame
有一个架构。
以博客 post 中将 RDD 转换为 DataFrame
为例:如果 DataFrame
与 Dataset[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]
显然,数据框实际上是行 和模式 的数据集。
在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() 也 returns RDD
,它从不 returns 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)
请注意(除了 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))