通过循环访问数据帧的所有其他列来确定列的值



我有一个列为 A-Z 的数据帧,我想根据是否有任何其他列值为 null 来分配 Z 的值。我可以通过以下方式做到这一点:

val df2 = df1.withColumn("Z",
   when(col("A") === lit(null), lit("Y"))
  .when(col("B") === lit(null), lit("Y"))
  .when(col("C") === lit(null), lit("Y"))
  ...
  ...
  .when(col("Y") === lit(null), lit("Y"))
  .otherwise(lit("N")));

是否有更简洁的方法可以迭代 withColumn 方法中的所有其他列?

是的,您可以遍历withColumns中的列,并将foldLeft用于逻辑表达式:

val df2 = df1.withColumn("Z",
      when(
        df.columns
          .filter(name => name.matches("[A-Z]")) // only take these column names
          .map(name => col(name)) // maps String to Column
          .foldLeft(lit(false))((acc, current) => when(acc or current.isNull, lit(true)).otherwise(lit(false)))
        , lit("Y"))
        .otherwise(lit("N"))
    )

测试:

输入:

+---+----+----+
|  A|   B|   C|
+---+----+----+
|  1|   2|   3|
|  1|null|   3|
|  1|null|null|
+---+----+----+

输出:

+---+----+----+---+
|  A|   B|   C|  Z|
+---+----+----+---+
|  1|   2|   3|  N|
|  1|null|   3|  Y|
|  1|null|null|  Y|
+---+----+----+---+

我通过探索spark.sql.functions包来实现这一点

val df2 = df1
  .withColumn("Z",when(array_contains(array(df1.columns.map(c=>lower(col(c))):_*),"null"),lit("Y")).otherwise(lit("N")))

相关内容

  • 没有找到相关文章

最新更新