如何根据某列的每个值为N组选择行?

时间:2015-09-24 10:08:53

标签: apache-spark apache-spark-sql

我有一个表格

Span     Available     Time
A            0          0
B            1          0
C            1          0
A            1          1
B            0          1
C            1          1
...         ...        ...
A            1          N
B            0          N
C            1          N

我希望将其分组为每Time个X Span s组。所以它看起来像:

Span     Available     Time
A            1           0
A            0           1
...         ...         ...
A            1           X
B            1           0
B            1           1
...         ...         ...
B            0           X
C            0           0
C            1           1
...         ...         ...
C            0           X
A            1          X+1
A            0          X+2
...         ...         ...
A            1          2X
B            1          X+1
B            1          X+2
...         ...         ...
B            0           2X
...         ...         ...
...         ...         ...
A            0          N-X
A            1          N-X+1
...         ...         ...
A            0           N
B            1          N-X
B            0          N-X+1
...         ...         ...
B            1           N
C            0          N-X
C            1          N-X+1
...         ...         ...
C            1           N

其中XN的因素。

如何使用SQL Spark的DataFrame API以这种方式对数据进行分组?

另外,如何通过每个跨度的X行聚合该表,以获得从时间0到X,X到2X等的跨度的百分比可用性?

编辑:

对于上下文,每组X行代表一天,整个数据集代表一周。所以我想每天汇总每天的可用性。

编辑:

另外,我知道X是什么。所以我希望能够说出类似GROUP BY Span LIMIT X ORDER BY Time

的内容

编辑:

作为更好地描述这个的最后一次尝试,我想要第一个跨度的第一个X,然后是下一个跨度的第一个X,然后是最后一个跨度的第一个X,然后是第一个跨度的下一个X. ,第二个跨度的下一个X等,直到每个跨度的最后一行。

1 个答案:

答案 0 :(得分:1)

假设您的时间列包含时间戳,并且您输入的数据看起来像这个示例rdd:

val rdd = sc.parallelize(List(("A", 0, "2015-01-02 09:00:00"),
                              ("A", 1, "2015-01-02 10:00:00"), 
                              ("A", 1, "2015-01-02 11:00:00"),
                              ("B", 0, "2015-01-02 09:00:00"),
                              ("B", 0, "2015-01-02 10:00:00"), 
                              ("B", 1, "2015-01-02 11:00:00"),
                              ("A", 1, "2015-01-03 09:00:00"),
                              ("A", 1, "2015-01-03 10:00:00"), 
                              ("A", 1, "2015-01-03 11:00:00"),
                              ("B", 0, "2015-01-03 09:00:00"),
                              ("B", 0, "2015-01-03 10:00:00"), 
                              ("B", 0, "2015-01-03 11:00:00")
))

你可以像这样实现你的分组和聚合:

rdd.map{case(span,availability,timestamp) => ((span,getDate(timestamp)), (List((availability, time)), availability, 1))}
  .reduceByKey((v1,v2) => (v1._1 ++ v2._1, v1._2 + v2._2, v1._3 + v2._3))
  .mapValues(v => (v._1, v._2.toDouble/v._3))

(其中getDate()是一个将从时间戳返回日期的函数。)

这将以(span,List((可用性,时间)),availability_percentage)的格式生成输出。对于我的示例rdd,结果将如下所示:

 (B,List((0,2015-01-02 09:00:00), (0,2015-01-02 10:00:00), (1,2015-01-02 11:00:00)),0.3333333333333333)
 (A,List((0,2015-01-02 09:00:00), (1,2015-01-02 10:00:00), (1,2015-01-02 11:00:00)),0.6666666666666666)
 (A,List((1,2015-01-03 09:00:00), (1,2015-01-03 10:00:00), (1,2015-01-03 11:00:00)),1.0)
 (B,List((0,2015-01-03 09:00:00), (0,2015-01-03 10:00:00), (0,2015-01-03 11:00:00)),0.0)