如何在spark scala中的数据帧上动态调用withColumn函数

Lux*_*Lux 0 scala apache-spark apache-spark-sql

这在 Spark-Scala 中可能吗?我使用的是火花2.2

val func="""withColumn("seq", lit("this is seq"))
           .withColumn("id", lit("this is id"))
           .withColumn("type", lit("this is type"))"""
Run Code Online (Sandbox Code Playgroud)

然后在数据框(df)之上使用上面的变量,如下所示

val df2=df.$func
Run Code Online (Sandbox Code Playgroud)

我将这些函数保存到变量的原因是我想根据条件动态应用函数。有时我可能需要 1 个 withColumn 函数,有时我可能需要多个 withColumn 函数。

感谢任何帮助。谢谢!

Sha*_*ala 5

如果我理解正确,那么你可以使用foldLeft

假设你有一个dataframedf 作为

val df: DataFrame = Seq(("123"), ("123"), ("223"), ("223")).toDF()
Run Code Online (Sandbox Code Playgroud)

您可以创建list列名称和您调用的操作/函数

val list = List(
  ("seq", lit("this is seq")),
  ("id", lit("this is id")),
  ("type" , lit("thisis type"))
)
Run Code Online (Sandbox Code Playgroud)

现在您可以foldLeft将此列表用作

list.foldLeft(df){(tempDF, listValue) =>
  tempDF.withColumn(listValue._1, listValue._2)
}
Run Code Online (Sandbox Code Playgroud)

更好的解决方案是从数据框中的上述值和列的列表中创建一个选择语句,如下所示

val columns = df.columns.map(col) ++ list.map(r => r._2 as r._1)
Run Code Online (Sandbox Code Playgroud)

最后结果:

+-----+-----------+----------+-----------+
|value|seq        |id        |type       |
+-----+-----------+----------+-----------+
|123  |this is seq|this is id|thisis type|
|123  |this is seq|this is id|thisis type|
|223  |this is seq|this is id|thisis type|
|223  |this is seq|this is id|thisis type|
+-----+-----------+----------+-----------+
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!