【问题标题】:Spark SQL window function look ahead and complex functionSpark SQL窗口函数前瞻和复杂函数
【发布时间】:2018-01-06 11:59:20
【问题描述】:

我有以下数据:

+-----+----+-----+
|event|t   |type |
+-----+----+-----+
| A   |20  | 1   |
| A   |40  | 1   |
| B   |10  | 1   |
| B   |20  | 1   |
| B   |120 | 1   |
| B   |140 | 1   |
| B   |320 | 1   |
| B   |340 | 1   |
| B   |360 | 7   |
| B   |380 | 1   |
+-----+-----+----+

而我想要的是这样的:

+-----+----+----+
|event|t   |grp |
+-----+----+----+
| A   |20  |1   |
| A   |40  |1   |
| B   |10  |2   |
| B   |20  |2   |
| B   |120 |3   |
| B   |140 |3   |
| B   |320 |4   |
| B   |340 |4   |
| B   |380 |5   |
+-----+----+----+

规则:

  1. 将彼此相距至少 50 毫秒的所有值组合在一起。 (第 t 列)并且属于同一事件。
  2. 当出现类型 7 的行时,也进行剪切并删除该行。 (见最后一行)

我可以通过this thread的答案实现的第一条规则:

代码:

val windowSpec= Window.partitionBy("event").orderBy("t")

 val newSession =  (coalesce(
  ($"t" - lag($"t", 1).over(windowSpec)),
  lit(0)
) > 50).cast("bigint")

val sessionized = df.withColumn("session", sum(newSession).over(userWindow))

我不得不说我无法弄清楚它是如何工作的,也不知道如何修改它,以便规则 2 也可以工作...... 希望有人能给我一些有用的提示。

我尝试了什么:

val newSession =  (coalesce(
  ($"t" - lag($"t", 1).over(windowSpec)),
  lit(0)
) > 50 || lead($"type",1).over(windowSpec) =!= 7 ).cast("bigint")

但只发生错误:“必须遵循方法;不能遵循org.apache.spark.sql.Column val grp = (coalesce(

【问题讨论】:

  • 如果您的窗口函数正在工作,那么只需在应用您的窗口函数之前过滤掉 type == 7 的行
  • @RameshMaharjan 我认为这行不通,因为如果你先删除它,你就不能再“剪切”了
  • 为什么事件 B 的 grp 在您的预期结果中从 2 开始?
  • 我的一个错误,但感谢您的解决方案

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


【解决方案1】:

这应该可以解决问题:

val newSession =  (coalesce(
  ($"t" - lag($"t", 1).over(win)),
  lit(0)
) > 50 
  or $"type"===7) // also start new group in this case
 .cast("bigint")

df.withColumn("session", sum(newSession).over(win))
.where($"type"=!=7) // remove these rows
.orderBy($"event",$"t")
.show

给予:

+-----+---+----+-------+
|event|  t|type|session|
+-----+---+----+-------+
|    A| 20|   1|      0|
|    A| 40|   1|      0|
|    B| 10|   1|      0|
|    B| 20|   1|      0|
|    B|120|   1|      1|
|    B|140|   1|      1|
|    B|320|   1|      2|
|    B|340|   1|      2|
|    B|380|   1|      3|
+-----+---+----+-------+

【讨论】:

    猜你喜欢
    • 2017-07-15
    • 2017-04-30
    • 1970-01-01
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多