如何在CASE语句

时间:2017-09-14 13:46:24

标签: apache-spark apache-spark-sql pyspark-sql

我有一个包含两列的数据框,listA存储为Seq[String]valB存储为String。我想创建第三列valC,它将是Int类型,其值为
iff valB is present in listA then 1 otherwise 0

我尝试了以下操作:

val dfWithAdditionalColumn = df.withColumn("valC", when($"listA".contains($"valB"), 1).otherwise(0))

但Spark未能执行此操作并发出以下错误:

cannot resolve 'contains('listA', 'valB')' due to data type mismatch: argument 1 requires string type, however, 'listA' is of array type.;

如何在CASE语句中使用数组类型列值?

谢谢, Devj

2 个答案:

答案 0 :(得分:2)

您应该使用array_contains

import org.apache.spark.sql.functions.{expr, array_contains}

df.withColumn("valC", when(expr("array_contains(listA, valB)"), 1).otherwise(0))

答案 1 :(得分:1)

你可以写一个简单的udf来检查元素是否存在于数组中:

val arrayContains = udf( (col1: Int, col2: Seq[Int]) => if(col2.contains(col1) ) 1 else 0 )

然后只需调用它并按正确的顺序传递必要的列:

df.withColumn("hasAInB", arrayContains($"a", $"b" ) ).show

+---+---------+-------+
|  a|        b|hasAInB|
+---+---------+-------+
|  1|   [1, 2]|      1|
|  2|[2, 3, 4]|      1|
|  3|   [1, 4]|      0|
+---+---------+-------+