我想强制转换数据框的架构以更改某些列的类型
使用Spark和Scala。

具体来说,我试图使用as [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)
    

I would like to cast the column "b" to Double. So I try the following:



    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应该具有以下架构



|-a:字符串(可为空= true)
|-b:双精度(nullable = false)



但是输出是


---------------------------使用(String Double)进行转换
+ --- + --- +
| a | b |
+ --- + --- +
| a | 1 |
| b | 2 |
+ --- + --- +


|-a:字符串(可为空= true)
|-b:整数(nullable = false)

---------------------------使用ClassData_Double进行转换
+ --- + --- +
| a | b |
+ --- + --- +
| a | 1 |
| b | 2 |
+ --- + --- +


|-a:字符串(可为空= true)
|-b:整数(nullable = false)



这表明“ b”列尚未转换为两倍。

关于我在做什么错的任何提示吗?

顺便说一句:我知道上一篇文章“如何在Spark SQL的DataFrame中更改列类型?” (请参见How to change column types in Spark SQL's DataFrame?)。我知道我可以一次更改一个列的类型,但是我正在寻找一种更通用的解决方案,可以一次更改整个数据的架构(并且我试图在此过程中了解Spark)。

最佳答案

好吧,由于函数是链接在一起的,并且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[], ...)}

关于scala - 在Spark和Scala中转换数据框的架构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40232615/

10-16 03:22
查看更多