복붙노트

[SCALA] 가변 인자와 스파크 UDF

SCALA

가변 인자와 스파크 UDF

이 문서에서와 같이 (22)에 모든 인수를 나열 할 수있는 유일한 방법인가?

https://spark.apache.org/docs/1.5.0/api/scala/index.html#org.apache.spark.sql.UDFRegistration

누구나이 비슷한 작업을 수행하는 방법을 알아 냈어?

sc.udf.register("func", (s: String*) => s......

(스킵의 널 (null)이 당시 2 개 인자에 있다고 정의 CONCAT 함수 작성)

감사

해결법

  1. ==============================

    1.UDF는 *하지 지원이 변수 인수 할 수 있지만 배열 기능을 사용하여 포장 열 임의의 수를 전달할 수 있습니다 :

    UDF는 *하지 지원이 변수 인수 할 수 있지만 배열 기능을 사용하여 포장 열 임의의 수를 전달할 수 있습니다 :

    import org.apache.spark.sql.functions.{udf, array, lit}
    
    val myConcatFunc = (xs: Seq[Any], sep: String) => 
      xs.filter(_ != null).mkString(sep)
    
    val myConcat = udf(myConcatFunc)
    

    사용 예 :

    val  df = sc.parallelize(Seq(
      (null, "a", "b", "c"), ("d", null, null, "e")
    )).toDF("x1", "x2", "x3", "x4")
    
    val cols = array($"x1", $"x2", $"x3", $"x4")
    val sep = lit("-")
    
    df.select(myConcat(cols, sep).alias("concatenated")).show
    
    // +------------+
    // |concatenated|
    // +------------+
    // |       a-b-c|
    // |         d-e|
    // +------------+
    

    원시 SQL로 :

    df.registerTempTable("df")
    sqlContext.udf.register("myConcat", myConcatFunc)
    
    sqlContext.sql(
        "SELECT myConcat(array(x1, x2, x4), '.') AS concatenated FROM df"
    ).show
    
    // +------------+
    // |concatenated|
    // +------------+
    // |         a.c|
    // |         d.e|
    // +------------+
    

    약간 더 복잡한 접근 방식은 대략이 같은 모든 및 작성 SQL 표현식에서 UDF를 사용하지 않습니다 :

    import org.apache.spark.sql.functions._
    import org.apache.spark.sql.Column
    
    def myConcatExpr(sep: String, cols: Column*) = regexp_replace(concat(
      cols.foldLeft(lit(""))(
        (acc, c) => when(c.isNotNull, concat(acc, c, lit(sep))).otherwise(acc)
      )
    ), s"($sep)?$$", "") 
    
    df.select(
      myConcatExpr("-", $"x1", $"x2", $"x3", $"x4").alias("concatenated")
    ).show
    // +------------+
    // |concatenated|
    // +------------+
    // |       a-b-c|
    // |         d-e|
    // +------------+
    

    하지만 난 당신이 PySpark 작동하지 않는 노력이 가치가 의심.

    * 당신이이 문법 설탕 모두에서 제거됩니다 변수 인수 및 UDF를 발생하는 ArrayType를 기대합니다 사용하여 함수를 전달하는 경우. 예를 들면 :

    def f(s: String*) = s.mkString
    udf(f _)
    

    형식이 될 것입니다 :

    UserDefinedFunction(<function1>,StringType,List(ArrayType(StringType,true)))
    
  2. from https://stackoverflow.com/questions/33151866/spark-udf-with-varargs by cc-by-sa and MIT license