我想转换数据框架构以更改某些列的类型 使用Spark和Scala。
具体来说,我试图用作[U]函数,其描述如下: “返回一个新的数据集,其中每条记录都已映射到指定的类型。 用于映射列的方法取决于U “
的类型原则上这正是我想要的,但我无法让它发挥作用。
// 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”尚未转换为加倍。
我做错了什么提示?
BTW:我知道上一篇文章“如何在Spark SQL的DataFrame中更改列类型?” (见How to change column types in Spark SQL's DataFrame?)。我知道我可以一次更改一个列的类型,但我正在寻找一个更通用的解决方案,一次性改变整个数据的模式(我正在尝试理解过程中的Spark)。
答案 0 :(得分:4)
好吧,因为函数被链接而且Spark做了懒惰的评估, 它实际上 一次性改变整个数据的模式,即使你把它写成当时更改一列,如下所示:
import spark.implicits._
df.withColumn("x", 'x.cast(DoubleType)).withColumn("y", 'y.cast(StringType))...
作为替代方案,我想你可以一次性使用map
进行演员表,例如:
df.map{t => (t._1, t._2.asInstanceOf[Double], t._3.asInstanceOf[], ...)}