Spark Scala:检查字符串是否不为空或为空

Spark Scala : Check if string isn't null or empty

首先,由于三值逻辑,这不仅仅是对 null 或空检查的任何有效实现的否定。

我想做一个函数 isNotNullish ,它尽可能接近 isNotNull 但也过滤掉空字符串。我 运行 遇到了一些涉及 column/column 类型如何工作以及三值逻辑的奇怪之处。到目前为止,我拥有的最好的是:

def isNotNullish(questionable: Column) : Column = {
  val oddish = questionable === lit("")
  questionable.isNotNull && (!oddish || oddish.isNull)
}

如果这看起来很奇怪,那是因为它确实如此。据我所知,如果该行包含 null 或(某些!)非字符串类型,则 questionable === lit("") 将为给定行 return null 。在三值逻辑中,true && null = null,这会导致 questionable.isNotNull && (questionable =!= lit("") 到 return null 在某些情况下我希望它 return true . questionable.isNotNull && (!oddish || oddish.isNull) 代码永远不会产生 null,总是 true 或 false。

这几乎不太有效:出于某种我不明白的原因,=== 比较很高兴 return 对于数字类型为 null,但对于复杂类型则失败。 (即使我正在尝试做的事情是不可能的或不可取的,我也希望对此有一个解释。)

检查架构并简单地对字符串类型进行与其他类型不同的测试可能更负责任,但据我所知,这需要将数据帧作为参数传递。我试图避免这种情况,特别是对于长序列的转换,其中所述参数可能是匿名的。

(在有人问之前,我知道以这种草率的方式处理 null 和类型在一般的 Scala 中会很糟糕,但我认为它在不同模式的 Spark/SQL/huge 数据帧的上下文中是不同的。具体情况是自动探索粗略数据,因此能够回答 "I don't know what the columns are, but tell me how often they hold actual values" 这样的问题很有用。)

你用这个有用吗<=>

    val employees = spark.createDataFrame(Seq(("E1","100.0"), ("E2","200.0"),("E3",null),("E4",""))).toDF("employee","salary")
    employees.show()
    employees.filter(notNullAndEmpty($"salary")).show()

  def notNullAndEmpty(c:Column): Column ={
    (c.isNotNull and !(c <=> lit("")))
  }

数据-

+--------+------+
|employee|salary|
+--------+------+
|      E1| 100.0|
|      E2| 200.0|
|      E3|  null|
|      E4|      |
+--------+------+

结果

+--------+------+
|employee|salary|
+--------+------+
|      E1| 100.0|
|      E2| 200.0|
+--------+------+