【问题标题】:Pass arguments to a udf from columns present in a list of strings从字符串列表中的列向 udf 传递参数
【发布时间】:2020-10-28 13:49:24
【问题描述】:

我有一个字符串列表,代表数据框中的列名。 我想将这些列中的参数传递给 udf。如何在 spark scala 中做到这一点?

   val actualDF = Seq(
             ("beatles", "help|hey jude","sad",4),
             ("romeo", "eres mia","old school",56)
            ).toDF("name", "hit_songs","genre","xyz")


   val column_list: List[String] = List("hit_songs","name","genre")

   // example udf
   val testudf = org.apache.spark.sql.functions.udf((s1: String, s2: String) => {
     // lets say I want to concat all values
   })


   val finalDF = actualDF.withColumn("test_res",testudf(col(column_list(0))))

从上面的示例中,我想将我的列表 column_list 传递给 udf。我不确定如何传递代表列名的完整字符串列表。虽然在 1 个元素的情况下,我看到我可以用 col(column_list(0))) 做到这一点。请支持。

【问题讨论】:

    标签: scala apache-spark apache-spark-sql


    【解决方案1】:

    替换

    testudf(col(column_list(0)))
    

    testudf(column_list: _*)
    

    这会将列表解释为多个单独的输入参数。

    【讨论】:

    • 这仅适用于 column_list 中的两个值,如果 column_list 有两个以上的值,它可能会失败。
    【解决方案2】:

    hit_songs 的类型为Seq[String],您需要将udf 的第一个参数更改为Seq[String]

    scala> singersDF.show(false)
    +-------+-------------+----------+
    |name   |hit_songs    |genre     |
    +-------+-------------+----------+
    |beatles|help|hey jude|sad       |
    |romeo  |eres mia     |old school|
    +-------+-------------+----------+
    
    scala> actualDF.show(false)
    +-------+----------------+----------+
    |name   |hit_songs       |genre     |
    +-------+----------------+----------+
    |beatles|[help, hey jude]|sad       |
    |romeo  |[eres mia]      |old school|
    +-------+----------------+----------+
    
    scala> column_list
    res27: List[String] = List(hit_songs, name)
    

    如下更改您的UDF

    // s1 is of type Seq[String]
    val testudf = udf((s1:Seq[String],s2:String) => {
        s1.mkString.concat(s2)
    })
    
    

    申请UDF

    scala> actualDF
    .withColumn("test_res",testudf(col(column_list.head),col(column_list.last)))
    .show(false)
    +-------+----------------+----------+-------------------+
    |name   |hit_songs       |genre     |test_res           |
    +-------+----------------+----------+-------------------+
    |beatles|[help, hey jude]|sad       |helphey judebeatles|
    |romeo  |[eres mia]      |old school|eres miaromeo      |
    +-------+----------------+----------+-------------------+
    

    没有 UDF

    scala> actualDF.withColumn("test_res",concat_ws("",$"name",$"hit_songs")).show(false) // Without UDF.
    +-------+----------------+----------+-------------------+
    |name   |hit_songs       |genre     |test_res           |
    +-------+----------------+----------+-------------------+
    |beatles|[help, hey jude]|sad       |beatleshelphey jude|
    |romeo  |[eres mia]      |old school|romeoeres mia      |
    +-------+----------------+----------+-------------------+
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-03
      • 1970-01-01
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      • 2021-03-22
      相关资源
      最近更新 更多