如何将两个或多个列合并为一个?

时间:2019-01-28 05:53:30

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

我有一个流数据框,我想在某些列上计算<messageAccumulationTimeout>2000</messageAccumulationTimeout> min

我不想在应用这些操作后分别得到avgmin的结果列,而是希望将最小值和平均值输出合并到单个列中。

数据框如下所示:

avg

我以为我会使用Scala元组,但这似乎不起作用:

+-----+-----+
|  1  |  2  |           
+-----+-----+-
|24   |  55 |
+-----+-----+
|20   |  51 |
+-----+-----+

所有使用的代码:

val res = List("1","2").map(name => (min(col(name)), avg(col(name))).as(s"result($name)"))

我期望在应用val res = List("1","2").map(name => (min(col(name)),avg(col(name))).as(s"result($name)")) val groupedByTimeWindowDF1 = processedDf.groupBy($"xyz", window($"timestamp", "60 seconds")) .agg(res.head, res.tail: _*) min数学表达式之后的输出为:

avg

我应该如何写表达式?

2 个答案:

答案 0 :(得分:2)

使用struct标准功能:

  

struct(colName:String,colNames:String *):列

     

结构(列:列*):列

     

创建一个包含多个输入列的新结构列。

这将为您提供值和(列的)名称。

val res = List("1","2").map(name => 
  struct(min(col(name)), avg(col(name))) as s"result($name)")
  ^^^^^^ HERE

当您想引用结构中的一个字段并且可以使用名称(而非索引)时,可以看到struct的力量。

q.select("structCol.name")

答案 1 :(得分:1)

您想要做的是将多个列的值合并到一个列中。为此,您可以使用array函数。在这种情况下,它将是:

val res = List("1","2").map(name => array(min(col(name)),avg(col(name))).as(s"result($name)"))

哪个会给你:

+------------+------------+
|   result(1)|   result(2)|
+------------+------------+
|[20.0, 22.0]|[51.0, 53.0]|
+------------+------------+