【问题标题】:Scala Spark Replace empty String with NULLScala Spark 用 NULL 替换空字符串
【发布时间】:2023-03-26 20:14:01
【问题描述】:

我在这里想要的是如果特定列中的值为空字符串,则将其替换为 null。

原因是我使用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")
)

在上面的例子中,我希望首先用列xx 填充resolved_id,如果它不为空,如果它为空,则用列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】:

这是性能更好的正确方法
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")
  }

【讨论】:

  • 我的意思是,when 子句没有性能问题。所以你可以使用它
  • 您可以再检查一下。现在您不需要使用otherwise 方法。 :)
  • =!= 不等于
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-09
  • 2016-01-22
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多