我想使用Spark和Scala来转换数据帧的模式以更改某些列的类型 .
具体来说,我试图使用[U]函数,其描述如下:“返回一个新的数据集,其中每个记录已映射到指定的类型 . 用于映射列的方法取决于U的类型”
原则上这正是我想要的,但我无法让它发挥作用 .
这是一个简单的例子,取自https://github.com/apache/spark/blob/master/sql/core/src/test/scala/org/apache/spark/sql/DatasetSuite.scala
// definition of data
val data = Seq(("a", 1), ("b", 2)).toDF("a", "b")
正如预期的那样,数据模式是:
root
|-- a: string (nullable = true)
|-- b: integer (nullable = false)
我想将列“b”强制转换为Double . 所以我尝试以下方法:
import session.implicits._;
println(" --------------------------- Casting using (String Double)")
val data_TupleCast=data.as[(String, Double)]
data_TupleCast.show()
data_TupleCast.printSchema()
println(" --------------------------- Casting using ClassData_Double")
case class ClassData_Double(a: String, b: Double)
val data_ClassCast= data.as[ClassData_Double]
data_ClassCast.show()
data_ClassCast.printSchema()
据我所知,as [u]的定义,新的DataFrames应具有以下架构
root
|-- a: string (nullable = true)
|-- b: double (nullable = false)
但输出是
--------------------------- Casting using (String Double)
+---+---+
| a| b|
+---+---+
| a| 1|
| b| 2|
+---+---+
root
|-- a: string (nullable = true)
|-- b: integer (nullable = false)
--------------------------- Casting using ClassData_Double
+---+---+
| a| b|
+---+---+
| a| 1|
| b| 2|
+---+---+
root
|-- a: string (nullable = true)
|-- b: integer (nullable = false)
这表明列“b”尚未被强制转换为双倍 .
关于我做错了什么的暗示?
顺便说一句:我知道上一篇文章"How to change column types in Spark SQL's DataFrame?"(见How to change column types in Spark SQL's DataFrame?) . 我知道我可以一次更改一个列的类型,但我正在寻找一个更通用的解决方案,一次性改变整个数据的模式(我试图在过程中理解Spark) .
1 回答
好吧,因为函数是链接的,Spark做了懒惰的评估,它实际上确实一次性改变了整个数据的模式,即使你把它写成当时更改一列,如下所示:
作为替代方案,我想你可以一次性使用
map
来做你的演员,比如: