Spark 1.5.2:在一个时间范围内对DataFrame行进行分组

时间:2016-02-18 22:39:51

标签: apache-spark apache-spark-sql

我有一个df,其中包含以下架构:

ts: TimestampType 
key: int 
val: int

dfts的升序排序。从行(0)开始,我想在一定的时间间隔内对数据帧进行分组。

例如,如果我说df.filter(row(0).ts + expr(INTERVAL 24 HOUR)).collect(),它应该返回行(0)的24小时时间窗口内的所有行。

有没有办法在Spark DF上下文中实现上述功能?

1 个答案:

答案 0 :(得分:1)

一般来说,这是一项相对简单的任务。您所需要的只是UNIX时间戳上的基本算术。首先让我们将所有时间戳转换为数字:

val dfNum = df.withColumn("ts", $"timestamp".cast("long"))

接下来让我们找到所有行的最小时间戳:

val offset = dfNum.agg(min($"ts")).first.getLong(0)

并用它来计算群组:

val aDay = lit(60 * 60 * 24)
val group = (($"ts" - lit(offset)) / aDay).cast("long")
val dfWithGroups = dfNum.withColumn("group", group)

最后,您可以将其用作分组列:

dfWithGroups.groupBy($"group").agg(min($"value")).

如果您想要有意义的间隔(可解释为时间戳),只需将组乘以aDay

显然,这不会处理复杂的情况,例如处理夏令时或闰秒,但在大多数情况下都应该足够好。如果你需要正确处理任何一个,你使用类似的逻辑使用JUD时间和UDF。