繁体   English   中英

使用带有选项字段的案例类将数据帧转换为数据集

[英]spark convert dataframe to dataset using case class with option fields

我有以下案例类:

case class Person(name: String, lastname: Option[String] = None, age: BigInt) {}

和以下json:

{ "name": "bemjamin", "age" : 1 }

当我尝试将数据框转换为数据集时:

spark.read.json("example.json")
  .as[Person].show()

它显示了以下错误:

线程“主要” org.apache.spark.sql.AnalysisException中的异常:给定输入列,无法解析“ lastname ”:[age,name];

我的问题是:如果我的模式是我的案例类,并且它定义了姓氏是可选的,那么as()是否应该进行转换?

我可以使用.map轻松修复此问题,但我想知道是否还有其他更清洁的替代方法。

我们还有一个解决上述问题的选项。需要2个步骤

  1. 确保将可能缺失的字段声明为可为空的Scala类型(例如Option [_])。

  2. 提供一个模式参数而不依赖于模式推断。例如,可以使用use Spark SQL Encoder

     import org.apache.spark.sql.Encoders val schema = Encoders.product[Person].schema 

您可以如下更新代码。

val schema = Encoders.product[Person].schema

val df = spark.read
           .schema(schema)
           .json("/Users/../Desktop/example.json")
           .as[Person]

+--------+--------+---+
|    name|lastname|age|
+--------+--------+---+
|bemjamin|    null|  1|
+--------+--------+---+

当您执行spark.read.json("example.json").as[Person].show() ,基本上是将数据帧读取为,

FileScan json [age#6L,name#7]

然后尝试应用Encoders for Person对象,从而获得AnalysisException,因为它无法从json文件中找到lastname

您可以通过提供一些具有姓氏的数据来暗示可能是姓氏是可选的,或者尝试以下操作:

val schema: StructType = ScalaReflection.schemaFor[Person].dataType.asInstanceOf[StructType]
val x = spark.read
      .schema(schema)
      .json("src/main/resources/json/x.json")
      .as[Person]
+--------+--------+---+
|    name|lastname|age|
+--------+--------+---+
|bemjamin|    null|  1|
+--------+--------+---+

希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM