Pyspark - 根据时间戳值加入时间戳窗口

时间:2017-08-07 15:32:29

标签: apache-spark pyspark

是否有任何有效的方法可以将时间戳窗口列表与时间戳值列表联系起来?

数据框A具有以下值:

+------------------------------------+---------------------------------------------+----------------------+
|userid       |                    window                   |total_unique_locations|
+------------------------------------+---------------------------------------------+----------------------+
|da24a375-962a|[2017-06-04 03:20:00.0,2017-06-04 03:25:00.0]|2                     |
|0fd2b419-d6ec|[2017-06-04 03:50:00.0,2017-06-04 03:55:00.0]|2                     |
|c8159400-fe0a|[2017-06-04 03:10:00.0,2017-06-04 03:15:00.0]|2                     |
|a4336494-3a10|[2017-06-04 03:00:00.0,2017-06-04 03:05:00.0]|3                     |
|b4590016-1af2|2017-06-04 03:45:00.0,2017-06-04 03:50:00.0] |2                     |
|03b33b0a-e94e|[2017-06-04 03:30:00.0,2017-06-04 03:35:00.0]|2                     |
|e5e4c972-6599|[2017-06-04 03:25:00.0,2017-06-04 03:30:00.0]|5                     |
|345e81fb-5e12|[2017-06-04 03:50:00.0,2017-06-04 03:55:00.0]|2                     |
|bedd88f1-3751|[2017-06-04 03:20:00.0,2017-06-04 03:25:00.0]|2                     |
|da401dab-e7f3|[2017-06-04 03:20:00.0,2017-06-04 03:25:00.0]|2                     |
+------------------------------------+---------------------------------------------+----------------------+

窗口的数据类型为struct<start:timestamp,end:timestamp>

数据框B具有以下值:

+------------------------------------+------------------+
|userid       |eventtime            |distance           |
+------------------------------------+------------------+
|9f034a1d-02c1|2017-06-04 03:00:00.0|0.17218625176420413|
|9f034a1d-02c1|2017-06-04 03:00:00.0|0.11145767867097957|
|9f034a1d-02c1|2017-06-04 03:00:00.0|0.14064932728588236|
|a3fac437-efcc|2017-06-04 03:00:00.0|0.08328915597349452|
|a3fac437-efcc|2017-06-04 03:00:00.0|0.07079054693441306|
+------------------------------------+------------------+

我尝试使用常规连接,但它不起作用,因为窗口和事件时间具有不同的数据类型。

A.join(B, A.userid == B.userid, A.window == B.eventtime).select("*")

有什么建议吗?

2 个答案:

答案 0 :(得分:3)

效率较低的解决方案是joincrossJoin beteween

a.join(b, col("eventtime").between(col("window.start"), col("window.end")))

更有效的解决方案是将eventtime转换为struct,其定义与用于现有窗口的定义相同。例如:

(b
    .withColumn("event_window", window(col("eventtime"), "5 minutes"))
    .join(a, col("event_window") == col("window")))

答案 1 :(得分:0)

由于窗口和事件时间的数据类型不同,因此无法加入这两者。

val result = A.join(B,
  A("userid") === B("userid") && 
  A("window.start") === B("eventtime") ||
  A("window.end") === B("eventtime"), "left")

希望这有帮助!