Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 在Spark数据帧中,若另一列中的值在广播变量数组中,则向新列添加值_Scala_Apache Spark_Merge_Apache Spark Sql - Fatal编程技术网

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)
)