Spark Dataframe na.fill 用于嵌套列

问题描述 投票:0回答:1

我试图在 Spark 中为具有空值的嵌套列设置默认值,但看起来 DataFrameNaFunctions.fill 函数不适用于嵌套列。

import spark.implicits._

case class Demographics(city: String)
case class Detail(age: Int, demographics: Demographics)
case class Person(name: String, details: Details

val data = Seq(Data(Person("James", Details(48, demographics=Demographics("Toronto")))), Data(Person("Mary", Details(41, demographics=Demographics(null)))), Data(null)).toDS

data.na.fill("default").show(false)
+------------------------+
|person                  |
+------------------------+
|{James, {48, {Toronto}}}|
|{Mary, {41, {NULL}}}    |
|NULL                    |
+------------------------+

What I am expecting:
+------------------------+
|person                  |
+------------------------+
|{James, {48, {Toronto}}}|
|{Mary, {41, {default}}}    |
|NULL                    |
+------------------------+

有人知道有什么方法可以做到这一点吗?顺便说一句,我想设置一个值的主要原因是因为我需要引用 JVM 对象,这些对象是 Java beans,并且这些字段不能为 null。

val encoder = Encoders.bean(classOf[InputBeanClass])
data.map(row => {
   row
})(encoder).count()

如果我运行上面的代码,我会收到以下错误:

If the schema is inferred from a Scala tuple/case class, or a Java bean, please try to use scala.Option[_] or other nullable types (e.g. java.lang.Integer instead of int/scala.Int).
scala apache-spark apache-spark-dataset
1个回答
0
投票

没有直接简单的方法可以做到这一点。 您有两个主要选择:

  1. 使用不允许 null 的 scala 类型 - 即您的嵌套字段永远不会为 null,而是“默认”。
    您可以编写自己的选项,例如使用 Default(X) 而不是 null 的 ADT,在这种情况下,您需要使用无框架注入之类的东西来展平嵌套结构以及交换到它的编码派生
  2. 在使用 bean 编码器之前,通过 withField(自 3.1 开始)对每个可空字段使用临时转换,将 null 替换为其字段适当的值
© www.soinside.com 2019 - 2024. All rights reserved.