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
不使用UDF从dataframe访问scala映射_Scala_Apache Spark_Apache Spark Sql_Rdd_User Defined Functions - Fatal编程技术网

不使用UDF从dataframe访问scala映射

不使用UDF从dataframe访问scala映射,scala,apache-spark,apache-spark-sql,rdd,user-defined-functions,Scala,Apache Spark,Apache Spark Sql,Rdd,User Defined Functions,我有一个Spark(1.6版)Dataframe,我想添加一个包含在Scala映射中的值的列,这是我的简化代码: val map = Map("VAL1" -> 1, "VAL2" -> 2) val df2 = df.withColumn("newVal", map(col("key"))) 这段代码不起作用,显然我收到了以下错误,因为映射在接收列时需要字符串值: found : org.apache.spark.sql.Column required: String 我能

我有一个Spark(1.6版)
Dataframe
,我想添加一个包含在Scala映射中的值的列,这是我的简化代码:

val map = Map("VAL1" -> 1, "VAL2" -> 2)
val df2 = df.withColumn("newVal", map(col("key")))
这段代码不起作用,显然我收到了以下错误,因为映射在接收列时需要字符串值:

found   : org.apache.spark.sql.Column
required: String
我能做到这一点的唯一方法是使用UDF:

val map = Map("VAL1" -> 1, "VAL2" -> 2)
val myUdf = udf{ value:String => map(value)}
val df2 = df.withColumn("newVal", myUdf($"key"))
如果可能的话,我希望避免使用UDF


是否有其他仅使用DataFrame API的解决方案可用(我也希望避免将其转换为RDD)?

TL;DR只需使用
udf

对于您使用的版本(根据您的评论,Spark 1.6)没有不需要
udf
map
覆盖
RDD
/
数据集的解决方案

在更高版本中,您可以:

  • 使用
    map
    函数(2.0或更高版本)创建literal
    MapType

    import org.apache.spark.sql.functions
    
    val map = functions.map(
       Map("VAL1" -> 1, "VAL2" -> 2)
         .flatMap { case (k, v) =>  Seq(k, v) } .map(lit) .toSeq: _*
    )
    map($"key")
    
  • typedLit
    (2.2或更高版本)创建literal
    MapType

    val map = functions.typedLit(Map("VAL1" -> 1, "VAL2" -> 2))
    map($"key")
    
直接使用


参考

您可以将地图转换为数据帧,并使用此数据帧与现有数据帧之间的连接。因为Map数据帧非常小,所以它应该是一个广播连接,并且避免了洗牌阶段的需要


让Spark知道如何使用广播连接如下所述:

您可以使用
数据集
或转换为RDD,获取映射值,然后再次转换为dataframe。我想我不能,因为我使用的是Spark 1.6,数据集是Beta版。如果可能的话,您能提供一个仅使用API数据帧的示例吗?我更新了我的问题谢谢@mattinbits,这就成功了。我重构了代码,创建了一个新的
数据框架
,并将其与现有的数据框架连接起来