Scala 在Spark数据帧中,若另一列中的值在广播变量数组中,则向新列添加值
我有一个数组作为广播变量,它包含整数:Scala 在Spark数据帧中,若另一列中的值在广播变量数组中,则向新列添加值,scala,apache-spark,merge,apache-spark-sql,Scala,Apache Spark,Merge,Apache Spark Sql,我有一个数组作为广播变量,它包含整数: broadcast_array.value Array(72159153, 72159163, 72159202, 72159203, 72159238, 72159398, 72159447, 72159448, 72159455, 72159492... 我在数据集中有一列(调用是col\u id,其中包含IntegerType值,这些值可能在广播数组中,但可能不在其中 我只想创建一个新列(称之为new\u col),检查每行的col\u id值是否
broadcast_array.value
Array(72159153, 72159163, 72159202, 72159203, 72159238, 72159398, 72159447, 72159448, 72159455, 72159492...
我在数据集中有一列(调用是col\u id
,其中包含IntegerType
值,这些值可能在广播数组中,但可能不在其中
我只想创建一个新列(称之为new\u col
),检查每行的col\u id
值是否在broadcast\u数组中。如果是这样,新列值应该是可用的
,否则可以是null
所以我有点像:
val my_new_df = df.withColumn("new_col", when(broadcast_array.value.contains($"col_id"), "Available"))
但我一直在犯这样的错误:
Name: Unknown Error
Message: <console>:45: error: type mismatch;
found : Boolean
required: org.apache.spark.sql.Column
val my_new_df = df.withColumn("new_col", when(broadcast_array.value.contains($"col_id"), "Available"))
^
StackTrace:
Name:未知错误
消息::45:错误:类型不匹配;
发现:布尔值
必需:org.apache.spark.sql.Column
val my_new_df=df.withColumn(“new_col”,when(broadcast_array.value.contains($“col_id”),“Available”))
^
堆栈跟踪:
最让我困惑的是,我认为when
语句需要一个输出布尔值的条件,但这里它说它需要一个列
根据现有列中的值是否可以在预定义数组中找到,如何向新列添加值?如果查看when
函数的api
def when(条件:org.apache.spark.sql.Column,值:scala.Any):org.apache.spark.sql.Column
很明显,所需的条件是列而不是布尔值
因此,您可以进行复杂的lit
组合,将布尔值
转换为列
import org.apache.spark.sql.functions._
df.withColumn("new_col", when(lit(broadcast_array.value.mkString(",")).contains($"col_id"), lit("Available"))).show(false)
或
通过编写一个简单的udf
函数
import org.apache.spark.sql.functions._
val broadcastContains = udf((id: Int) => broadcast_array.value.contains(id))
df.withColumn("new_col", when(broadcastContains($"col_id"), lit("Available"))).show(false)
只需将函数调用为
import org.apache.spark.sql.functions._
val broadcastContains = udf((id: Int) => broadcast_array.value.contains(id))
df.withColumn("new_col", when(broadcastContains($"col_id"), lit("Available"))).show(false)
我添加了一个broadcastArrayContains
函数,使Ramesh的解决方案更加可重用/可访问
def broadcastArrayContains[T](col: Column, broadcastedArray: Broadcast[Array[T]]) = {
when(col.isNull, null)
.when(lit(broadcastedArray.value.mkString(",")).contains(col), lit(true))
.otherwise(lit(false))
}
假设您有以下数据帧(df
):
您可以按如下方式标识广播数组中的所有值:
val specialNumbers = spark.sparkContext.broadcast(Array("123", "456"))
df.withColumn(
"is_special_number",
functions.broadcastArrayContains[String](col("num"), specialNumbers)
)