#scala #apache-spark #apache-spark-sql
#scala #apache-spark #apache-spark-sql
Вопрос:
У меня есть список строк, которые представляют имена столбцов внутри фрейма данных. Я хочу передать аргументы из этих столбцов в 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)))
. Пожалуйста, поддержите.
Ответ №1:
Заменить
testudf(col(column_list(0)))
с
testudf(column_list: _*)
Это интерпретирует список как несколько отдельных входных аргументов.
Комментарии:
1. Это будет работать только для двух значений в
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 |
------- ---------------- ---------- -------------------