Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.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 Udf中传递地图?_Scala_Apache Spark_User Defined Functions - Fatal编程技术网

Scala 如何在Spark Udf中传递地图?

Scala 如何在Spark Udf中传递地图?,scala,apache-spark,user-defined-functions,Scala,Apache Spark,User Defined Functions,我有个问题。我有一个spark数据框,其中有几列,如下所示: id颜色 1个红色、蓝色和黑色 2红色、绿色 3蓝色、黄色、绿色 我还有一个地图文件,看起来像: 红色,0 蓝色,1 绿色,2 黑色,3 黄色,4 我需要做的是将颜色名称映射到不同的ID中,例如将“Red、Blue、Black”映射到[1,1,0,1,0]的数组中。 我这样写代码: def mapColor(label_string:String):Array[Int]={ var labels = label_string.spl

我有个问题。我有一个spark数据框,其中有几列,如下所示:

id颜色
1个红色、蓝色和黑色
2红色、绿色
3蓝色、黄色、绿色

我还有一个地图文件,看起来像:
红色,0
蓝色,1
绿色,2
黑色,3
黄色,4

我需要做的是将颜色名称映射到不同的ID中,例如将“Red、Blue、Black”映射到[1,1,0,1,0]的数组中。 我这样写代码:

def mapColor(label_string:String):Array[Int]={
var labels = label_string.split(",")
var index_array = new Array[Int](COLOR_LENGTH)
for (label<-labels){
  if(COLOR_MAP.contains(label)){
    index_array(COLOR_MAP(label))=1
  }
  else{
    //dictionary does not contain the label, the last index set to be one
    index_array(COLOR_LENGTH-1)=1
  }
}
index_array 
}
 val color_function = udf(mapColor:(String)=>Array[Int])
 sql.withColumn("color_idx",color_function(col("Color")))
因为我有多个列需要这个操作,但是不同的列需要不同的字典。目前,我为每一列复制了这个函数(只需更改字典和长度信息)。但是代码看起来很乏味。是否有任何方法,我可以将长度和字典传递到映射函数中,例如

def map(label_string:String,map:Map[String,Integer],len:Int):Array[Int] 
但是我应该如何在spark数据帧中调用这个函数呢?因为我无法在声明中传递参数

val color_function = udf(mapColor:(String)=>Array[Int])

可以使用颜色贴图附带的UDF作为基本参数,如以下示例所示:

val df = Seq(
  (1, "Red, Blue, Black"),
  (2, "Red, Green"),
  (3, "Blue, Yellow, Green")
).toDF("id", "color")

val colorMap = Map("Red"-> 0, "Blue"->1, "Green"->2, "Black"->3, "Yellow"->4)

def mapColorCode(m: Map[String, Int]) = udf( (s: String) =>
  s.split("""\s*,\s*""").map(c => m.getOrElse(c, -99))
)

df.select($"id", mapColorCode(colorMap)($"color").as("colorcode")).show
// +---+----------+
// | id| colorcode|
// +---+----------+
// |  1| [0, 1, 3]|
// |  2|    [0, 2]|
// |  3| [1, 4, 2]|
// +---+----------+

以下是简短的完整代码-

val colrMapList = List("Red" -> 0, "Blue" -> 1, "Green" -> 2).toMap

def getColor = udf((colors: Seq[String]) => { if(!colors.isEmpty) colors.map(color => colrMapList.getOrElse(color,"0")).mkString(",") else "0"  } )

val colors = List((1, Array("Red","Blue","Black")),(2,Array("Red", "Green")))
val colrDF = sc.parallelize(colors).toDF

colrDF.withColumn("colorMap", getColor($"colors")).show
解释

  • 为颜色到整数映射创建一个
    映射
  • 函数提取给定颜色的相应整数
  • 最后,应用
    colrDF
    的函数来获得输出

  • 虽然这看起来是一个解决方案,但如果你能在其中添加一些词语,那就太好了。是因为答案没有解释就贴出来了吗?在这个UDF中如何处理map有什么建议吗