【发布时间】: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 |
+-----+----+----+
规则:
- 将彼此相距至少 50 毫秒的所有值组合在一起。 (第 t 列)并且属于同一事件。
- 当出现类型 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