我有一个列为 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")))