基于时间间隔PySpark分配组ID

gorkyyrv  于 2023-03-17  发布在  Spark
关注(0)|答案(1)|浏览(169)

我有一个如下所示的PySpark数据框(snap - i可以有多个日期)

UID Time
1   10/1/2016 7:25:52 AM
1   10/1/2016 8:53:38 AM
1   10/1/2016 11:18:50 AM
1   10/1/2016 11:19:32 AM
2   10/1/2016 10:25:36 AM
2   10/1/2016 10:28:08 AM
3   10/1/2016 10:57:41 AM
3   10/1/2016 8:57:10 PM

我想为用户在前一次操作之后最多N小时内执行的每一组操作分配一个唯一标识符。例如,如果时间范围为3小时,则输出应该如下所示:

UID Time                   GROUP_ID
1   10/1/2016 7:25:52 AM   1
1   10/1/2016 8:53:38 AM   1
1   10/1/2016 11:18:50 AM  1
1   10/1/2016 3:19:32 PM   2
2   10/1/2016 10:25:36 AM  3
2   10/1/2016 10:28:08 AM  3
3   10/1/2016 10:57:41 AM  4
3   10/1/2016 8:57:10 PM   5

有人帮忙吗?
谢谢

oug3syen

oug3syen1#

考虑这个问题的一种方法是将时间差除以您想要的间隔,这就得到了一个时间段。
然后,dense_rank得到一个连续的组号。

# interval in seconds
interval = 3 * 60 * 60
w = Window.partitionBy('id').orderBy('time')
df = (df.withColumn('time', F.to_timestamp('time', 'M/d/yyyy h:mm:ss a'))
      .withColumn('grp', F.floor(
          (F.col('time').cast('long') - F.min('time').over(w).cast('long')) 
           / interval))
      .withColumn('grp', F.dense_rank().over(Window.orderBy('id', 'grp'))))

结果

+---+-------------------+---+
| id|               time|grp|
+---+-------------------+---+
|  1|2016-10-01 07:25:52|  1|
|  1|2016-10-01 08:53:38|  1|
|  1|2016-10-01 11:18:50|  2|  # this is different from your expected result. but this is more than 3hrs since 7:25
|  1|2016-10-01 11:19:32|  2|
|  1|2016-10-01 20:00:00|  3|
|  2|2016-10-01 10:25:36|  4|
|  2|2016-10-01 10:28:08|  4|
|  3|2016-10-01 10:57:41|  5|
|  3|2016-10-01 20:57:10|  6|
+---+-------------------+---+

相关问题