如何在Spark中收集和处理列式数据

时间:2018-01-05 19:17:16

标签: scala apache-spark spark-dataframe

我有一个包含7天24小时数据的数据框,因此它有144列。

id     d1h1  d1h2   d1h3 .....  d7h24 
aaa    21     24     8   .....   14       
bbb    16     12     2   .....   4
ccc    21      2     7   .....   6

我想要做的是找到每天最多3个值:

id    d1        d2       d3  ....   d7
aaa  [22,2,2] [17,2,2] [21,8,3]    [32,11,2]
bbb  [32,22,12] [47,22,2] [31,14,3]    [32,11,2]
ccc  [12,7,4] [28,14,7] [11,2,1]    [19,14,7] 

2 个答案:

答案 0 :(得分:1)

定义模式:

val p = "^(d[1-7])h[0-9]{1,2}$".r

组列:

import org.apache.spark.sql.functions._

val cols = df.columns.tail
  .groupBy { case p(d) => d }
  .map { case (c, cs) =>  {
    val sorted = sort_array(array(cs map col: _*), false)
    array(sorted(0), sorted(1), sorted(2)).as(c)
  }}

选择:

df.select($"id" +: cols.toSeq: _*)

答案 1 :(得分:1)

import org.apache.spark.sql.functions._
var df = ...
val first3 = udf((list : Seq[Double]) => list.slice(0,3))
for (i <- 1 until 7) {
    val columns = (1 until 24).map(x=> "d"+i+"h"+x)
    df = df
        .withColumn("d"+i, first3(sort_array(array(columns.head, columns.tail :_*), false)))
        .drop(columns :_*)
}

这应该可以满足您的需求。事实上,每天我将24小时聚合到一个数组列中,我按顺序排序,然后从中选择前3个元素。