我有一个如下所示的场景,我需要为每个id值查找一个序列,如果找到匹配项,则需要获取相应的名称并在数据框中填充Name列(我故意保留这种方式以避免加入)。 场景
我能够创建一个可以完成此任务的通用方法,但是此实现的问题是如果Array太大,则会炸毁datanode堆空间。
v1:不缩放
def colTransform(refCol: String,newCol: String,lookUpArray: Array[Seq[Any]],index: Int)(df: DataFrame): DataFrame = {
df.withColumn(newCol,
concat_ws("",array(
lookUpArray.map{c =>
when(col(refCol).contains(c(0)), c(index).toString).otherwise(lit(""))
}: _*
)
)
)
}
第二个版本比较简单,但是存在一个细微的问题
def colTransform(
refCol: String,newCol: String,lookUpArray: Array[Seq[Any]],index: Int)(df: DataFrame): DataFrame = {
df.withColumn(newCol,
lit(s"${lookUpArray.filter{c =>
df(refCol) == lit(c(0))
}.map{c => if (c.length == 0) "Unknown" else c(index)}.mkString("")}")
)
}
问题是,应用于lookUpArray(第3行)的filter方法期望一个布尔值..所以我提供了df(refCol)== lit(c(0))..但总会得出false,因为左边的类型是Column,右边的类型是String。它可以编译并运行,但是最终结果是一个空列(因为所有内容都被过滤掉了,然后在空Seq上的mkString(“”)会导致“”。)。 如果您有任何建议或想法,请告诉我。