【问题标题】:How to convert a simple DataFrame to a DataSet Spark Scala with case class?如何将简单的 DataFrame 转换为带有案例类的 DataSet Spark Scala?
【发布时间】:2019-01-14 00:16:21
【问题描述】:

我正在尝试从 Spark 中的示例将简单的 DataFrame 转换为 DataSet: https://spark.apache.org/docs/latest/sql-programming-guide.html

case class Person(name: String, age: Int)    
import spark.implicits._

val path = "examples/src/main/resources/people.json"

val peopleDS = spark.read.json(path).as[Person]
peopleDS.show()

但是会出现以下问题:

Exception in thread "main" org.apache.spark.sql.AnalysisException: Cannot up cast `age` from bigint to int as it may truncate
The type path of the target object is:
- field (class: "scala.Int", name: "age")
- root class: ....

谁能帮帮我?

编辑 我注意到使用 Long 而不是 Int 可以工作! 这是为什么呢?

还有:

val primitiveDS = Seq(1,2,3).toDS()
val augmentedDS = primitiveDS.map(i => ("var_" + i.toString, (i + 1).toLong))
augmentedDS.show()

augmentedDS.as[Person].show()

打印:

+-----+---+
|   _1| _2|
+-----+---+
|var_1|  2|
|var_2|  3|
|var_3|  4|
+-----+---+

Exception in thread "main"
org.apache.spark.sql.AnalysisException: cannot resolve '`name`' given input columns: [_1, _2];

谁能帮我理解这里?

【问题讨论】:

    标签: scala apache-spark apache-spark-sql


    【解决方案1】:

    如果您将 Int 更改为 Long(或 BigInt),它可以正常工作:

    case class Person(name: String, age: Long)
    import spark.implicits._
    
    val path = "examples/src/main/resources/people.json"
    
    val peopleDS = spark.read.json(path).as[Person]
    peopleDS.show()
    

    输出:

    +----+-------+
    | age|   name|
    +----+-------+
    |null|Michael|
    |  30|   Andy|
    |  19| Justin|
    +----+-------+
    

    编辑: Spark.read.json 默认将数字解析为 Long 类型 - 这样做更安全。 您可以在使用 cast 或 udfs 后更改 col 类型。

    EDIT2:

    要回答您的第二个问题,您需要正确命名列,然后才能转换为 Person:

    val primitiveDS = Seq(1,2,3).toDS()
    val augmentedDS = primitiveDS.map(i => ("var_" + i.toString, (i + 1).toLong)).
     withColumnRenamed ("_1", "name" ).
     withColumnRenamed ("_2", "age" )
    augmentedDS.as[Person].show()
    

    输出:

    +-----+---+
    | name|age|
    +-----+---+
    |var_1|  2|
    |var_2|  3|
    |var_3|  4|
    +-----+---+
    

    【讨论】:

      【解决方案2】:

      这是从案例类创建数据集的方式

      case class Person(name: String, age: Long) 
      

      将案例类保留在具有以下代码的类之外

      val primitiveDS = Seq(1,2,3).toDS()
      val augmentedDS = primitiveDS.map(i => Person("var_" + i.toString, (i + 1).toLong))
      augmentedDS.show()
      
      augmentedDS.as[Person].show()
      

      希望这有帮助

      【讨论】:

      • 不!他们不是!我只有 3 个值:null、30 和 19!
      猜你喜欢
      • 2023-02-24
      • 1970-01-01
      • 1970-01-01
      • 2015-03-25
      • 2017-04-03
      • 2021-06-13
      • 2021-07-14
      • 2020-09-02
      • 2017-04-17
      相关资源
      最近更新 更多