Scala Spark用NULL替换空String

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

我想要的是将特定列中的值替换为null,如果它是空String。

原因是我使用org.apache.spark.sql.functions.coalesce根据另一列填充Dataframe的一列,但我注意到在某些行中值为empty String而不是null,因此coalesce函数无法按预期工作。

val myCoalesceColumnorder: Seq[String] = Seq("xx", "yy", "zz"),

val resolvedDf = df.select(
   df("a"),
   df("b"),
   lower(org.apache.spark.sql.functions.coalesce(myCoalesceColumnorder.map(x => adjust(x)): _*)).as("resolved_id")
)

在上面的例子中,我预计首先用resolved_id列填充xx,如果它不为null,如果它与列yy为空,依此类推。但是,因为有时列xx填充""而不是null,我在'resolved_id'中得到""

我试图修复它

resolvedDf.na.replace("resolved_id", Map("" -> null))

但基于na.replace文档,它只有在密钥和值都是BoleanStringDouble时才有效,所以我不能在这里使用null

我不想因为性能问题而使用UDF,我只是想知道有没有其他技巧来解决这个问题?

我可以解决这个问题的另一种方法是使用when但不确定性能

resolvedDf
      .withColumn("resolved_id", when(col("resolved_id").equalTo(""), null).otherwise(col("resolved_id")))
scala apache-spark apache-spark-sql
1个回答
0
投票

这是具有更好性能的正确方法 resolvedDf.withColumn("resolved_id", when($"resolved_id" !== "", $"resolved_id"))

基本上不需要使用otherwise方法。

您可以查看来源::: https://github.com/apache/spark/blob/master/sql/core/src/main/scala/org/apache/spark/sql/Column.scala#L507

/**
   * Evaluates a list of conditions and returns one of multiple possible result expressions.
   * If otherwise is not defined at the end, null is returned for unmatched conditions.
   *
   * {{{
   *   // Example: encoding gender string column into integer.
   *
   *   // Scala:
   *   people.select(when(people("gender") === "male", 0)
   *     .when(people("gender") === "female", 1)
   *     .otherwise(2))
   *
   *   // Java:
   *   people.select(when(col("gender").equalTo("male"), 0)
   *     .when(col("gender").equalTo("female"), 1)
   *     .otherwise(2))
   * }}}
   *
   * @group expr_ops
   * @since 1.4.0
   */
  def when(condition: Column, value: Any): Column = this.expr match {
    case CaseWhen(branches, None) =>
      withExpr { CaseWhen(branches :+ ((condition.expr, lit(value).expr))) }
    case CaseWhen(branches, Some(_)) =>
      throw new IllegalArgumentException(
        "when() cannot be applied once otherwise() is applied")
    case _ =>
      throw new IllegalArgumentException(
        "when() can only be applied on a Column previously generated by when() function")
  }
© www.soinside.com 2019 - 2024. All rights reserved.