Scala 从映射中获取列值作为spark数据帧中的键

Scala 从映射中获取列值作为spark数据帧中的键,scala,apache-spark,dataframe,Scala,Apache Spark,Dataframe,我要从作为键的列值映射中获取一个值,并创建一个新列 我试过以下方法 val testMap = Map("abc" -> "1234", "xyz" -> "3456") def checkthemap (testmap: Map[String, String], key: String) : String = { val value = testmap.get(key) if (value == null) "" else value.toString } va

我要从作为键的列值映射中获取一个值,并创建一个新列

我试过以下方法

val testMap = Map("abc" -> "1234", "xyz" -> "3456")

def checkthemap (testmap: Map[String, String], key: String) : String = {
    val value = testmap.get(key)
    if (value == null) "" else value.toString
}

val testDF = analysis
    .withColumn("test", lit(checkthemap(testMap,$"col")))
import org.apache.spark.sql.functions.{coalesce, lit, typedLit}

方法接受字符串而不是列。如何更改withColumn语句以将列值作为字符串发送给方法。

我建议使用UDF(用户定义函数),将列作为传入的查找映射的
,以返回相应的映射值,如下所示:

import org.apache.spark.sql.functions._
import spark.implicits._

def getMapValue(m: Map[String, String], defaultValue: String) = udf{
  (key: String) => m.getOrElse(key, defaultValue)
}

val df = Seq(
  (1, "a"), (2, "b"), (3, "c")
).toDF("id", "key")

val lookupMap = Map("a" -> "xx", "c" -> "zz")

df.withColumn("value", getMapValue(lookupMap, "")($"key")).show
// +---+---+-----+
// | id|key|value|
// +---+---+-----+
// |  1|  a|   xx|
// |  2|  b|     |
// |  3|  c|   zz|
// +---+---+-----+
编辑:有关使用内置Spark函数的解决方案,请参见另一个答案,该函数通常比UDF性能更好。

公认的答案效率非常低,而且不必要地复杂。相反,您应该将
testMap
视为一个文本。导入以下内容

val testMap = Map("abc" -> "1234", "xyz" -> "3456")

def checkthemap (testmap: Map[String, String], key: String) : String = {
    val value = testmap.get(key)
    if (value == null) "" else value.toString
}

val testDF = analysis
    .withColumn("test", lit(checkthemap(testMap,$"col")))
import org.apache.spark.sql.functions.{coalesce, lit, typedLit}
将映射转换为列:

val testMapCol = typedLit(testMap)
只需选择:

df.withColumn("value", coalesce(testMapCol($"col"), lit(""))

我认为您可以使用内置的函数元素

它的定义是:若列是数组,则返回数组中给定索引处的元素如果列是map,则返回给定键入值的值。

import org.apache.spark.sql.functions.{element_at, col, typedLit}
df.withColumn("value", element_at(typedLit(testMap), col("colName")))

我对前面的答案有一些问题,因为我不能在一列中添加元素_at。试试(火花3+)


出于某种原因,我不想创建到列或数据帧的映射。我想从方法本身访问它。还有其他选择吗?@user11425401关于此UDF问题的任何建议plz元素_at会收到一个文本,其中键的数据类型作为第二个参数,因此使用column对象会引发异常。