美文网首页Spark 应用
sparkSQL中UDF的使用

sparkSQL中UDF的使用

作者: breeze_lsw | 来源:发表于2016-08-15 15:11 被阅读443次

    在spark中使用sql时一些功能需要自定义方法实现,这时候就可以使用UDF功能来实现

    多参数支持

    UDF不支持参数*的方式输入多个参数,例如String*,不过可以使用array来解决这个问题。

    定义udf方法,此处功能是将多个字段合并为一个字段

    def allInOne(seq: Seq[Any], sep: String): String = seq.mkString(sep)
    

    在sql中使用

    sqlContext.udf.register("allInOne", allInOne _)
    
    //将col1,col2,col3三个字段合并,使用','分割
    val sql =
        """
          |select allInOne(array(col1,col2,col3),",") as col
          |from tableName
        """.stripMargin
    sqlContext.sql(sql).show()
    

    在DataFrame中使用

    import org.apache.spark.sql.functions.{udf,array,lit}
    val myFunc = udf(allInOne _)
    val cols = array("col1","col2","col3")
    val sep = lit(",")
    df.select(myFunc(cols,sep).alias("col")).show()
    

    一些简单的例子

    1.个数统计

    表结构如下,统计出每个人的爱好个数

    name hobbies
    alice jogging,Coding,cooking
    lina travel,dance
    # 将某个字段中逗号分隔的数量统计出来
    sqlContext.udf.register("hobby_num", (s: String) => s.split(',').size)
    sqlContext.sql("select *,hobby_num(hobbies) as hobby_num from table")
    

    结果

    name hobbies hobby_num
    alice read book,coding,cooking 3
    lina travel,dance 2

    2.空值填补

    表结构如下

    A B
    null 123456
    234234 234234
    # 填补第一个字段的空值
    sqlContext.udf.register("combine", (s1: String,s2: String)=> {if(s1 == null) s2 else s1})
    sqlContext.sql("select combine(A,B) as A from table")
    

    结果

    A
    123456
    234234

    3. 类型转化

    类型转化,将 String 转化为 Int

    sqlContext.udf.register("str2Int", (s: String) => s.toInt)
    

    或者直接使用cast

    sqlContext.sql("select cast(a AS Int) from table")
    

    4. 综合运用

    原始数据,ID(用户名),loginIP(帐号登录的ip地址)

    ID loginIP
    alice ip1
    lina ip2
    sven ip3
    alice ip1
    sven ip2
    alice ip4

    计算每个用户在哪些ip登录过,并统计数量

    ID ip_list loginIP_num
    alice ip1,ip4 2
    lina ip2 1
    sven ip2,ip3 2
    //统计数量
    sqlContext.udf.register("list_size", (s: String) => s.split(',').size)
    val sql =
        """select ID,ip_list,list_size(ip_list) as loginIP_num
          |from (select ID,concat_ws(',',collect_set(loginIP)) as ip_list from table)
        """.stripMargin
    sqlContext.sql(sql)
    

    相关文章

      网友评论

        本文标题:sparkSQL中UDF的使用

        本文链接:https://www.haomeiwen.com/subject/dzuusttx.html