spark scala udf:java.lang.unsupportedoperationexception:不支持任何类型的架构

fkaflof6  于 2021-07-13  发布在  Spark
关注(0)|答案(2)|浏览(319)

我试图返回一个Map,从自定义项与在如果否则,并得到以下例外,任何指针请?
java.lang.unsupportedoperationexception:不支持任何类型的架构

import org.apache.spark.sql.functions.{col, udf}
import org.apache.spark.sql.functions._
val df2  = Seq(
  ("1", Map("Fld1" -> "USA","Fld2" -> "UK")),
  ("2", Map("Fld1" -> "Germany", "Fld2" -> "Portugal")),
("3", Map("Fld1" -> "France", "Fld2" -> "Paris"))
).toDF("id", "map")

val getmapUdf  = udf((map1: Map[String, String]) => { 

    val fl1 = map1.getOrElse("Fld1","unknown")   
    val fl2 = map1.getOrElse("Fld2","unknown")   

     if (fl1 =="Germany")
    {
            Map("key1" -> "G")
    }
    else if(fl1 =="France") 
    {
        if (fl2 =="UK")
        {
            Map("key1" ->"U")
        }
        else
        {
            Map("key1" ->"Y")
        }
    }
    else if(fl1 =="France") 
    {
           Map("key1" ->"G")
    }

})
var temp2 = df2.withColumn("mymap", getmapUdf($"map"))
temp2.show(false)
dgiusagp

dgiusagp1#

得到这个错误是因为您的udf函数并不总是返回类型 Map[String,String] ,您使用的if/else语句在不满足条件时不包含默认值,因此返回类型为any。
但是,实际上,您可以在不使用udf的情况下使用 when 功能:

var temp2 = df2.withColumn(
  "mymap",
  when($"map" ("Fld1") === "Germany", map(lit("key1"), lit("G")))
    when ($"map" ("Fld1") === "France" && $"map" ("Fld2") === "UK", map(lit("key1"),lit("G")))
    when ($"map" ("Fld1") === "France", map(lit("key1"), lit("Y")))
)

temp2.show(false)

//+---+-----------------------------------+-----------+
//|id |map                                |mymap      |
//+---+-----------------------------------+-----------+
//|1  |[Fld1 -> USA, Fld2 -> UK]          |null       |
//|2  |[Fld1 -> Germany, Fld2 -> Portugal]|[key1 -> G]|
//|3  |[Fld1 -> France, Fld2 -> Paris]    |[key1 -> Y]|
//+---+-----------------------------------+-----------+

无论如何,如果您想使用自定义项,请修改函数以返回 Option[Map[String,String]] . 像这样:

val getmapUdf = udf((map1: Map[String, String]) => {
  val fl1 = map1.getOrElse("Fld1", "unknown")
  val fl2 = map1.getOrElse("Fld2", "unknown")

  if (fl1 == "Germany") {
    Some(Map("key1" -> "G"))
  } else if (fl1 == "France") {
    if (fl2 == "UK") {
      Some(Map("key1" -> "U"))
    } else {
      Some(Map("key1" -> "Y"))
    }
  } else if (fl1 == "France") {
    Some(Map("key1" -> "G"))
  } else {
    None
  }
})
jtw3ybtb

jtw3ybtb2#

如果你想继续使用你正在做的事情,我将尝试在这里提供一个替代答案,但是@blackbishop answer涵盖了实现相同内容的大多数选项。
为了使代码正常工作,只需在自定义项中进行更改,以确保有else条件返回如下所示的默认Map,然后就不会出现该错误。

val getmapUdf  = udf((map1: Map[String, String]) => { 

    val fl1 = map1.getOrElse("Fld1","unknown")   
    val fl2 = map1.getOrElse("Fld2","unknown")   

     if (fl1 =="Germany")
    {
            Map("key1" -> "G")
    }
    else if(fl1 =="France") 
    {
        if (fl2 =="UK")
        {
            Map("key1" ->"U")
        }
        else
        {
            Map("key1" ->"Y")
        }
    }
    else if(fl1 =="France") 
    {
           Map("key1" ->"G")
    }
  else
  {
    Map("key1" -> "unknown")
  }

})

相关问题