Skip to main content
 首页 » 编程设计

python之如何在 PySpark 中一天内累积超过 '1 hour' 个窗口

2024年08月16日34findumars

我有一个如下所示的 Spark DataFrame:

+---------+--------------------------+ 
|group_id |event_time                | 
+---------+--------------------------+ 
|XXXX     |2017-10-25 14:47:02.717013| 
|XXXX     |2017-10-25 14:47:25.444979| 
|XXXX     |2017-10-25 14:49:32.21353 | 
|YYYY     |2017-10-25 14:50:38.321134| 
|YYYY     |2017-10-25 14:51:12.028447| 
|ZZZZ     |2017-10-25 14:51:24.810688| 
|YYYY     |2017-10-25 14:37:34.241097| 
|ZZZZ     |2017-10-25 14:37:24.427836| 
|XXXX     |2017-10-25 14:37:24.620864| 
|YYYY     |2017-10-25 14:37:24.964614| 
+---------+--------------------------+ 

我想计算每个 group_id 一天内每小时事件的滚动计数。

因此,对于日期时间 25-10 14:00 和 group_id,我想计算该 group_id 的事件数> 从 25-10 00:00 到 25-10 14:00。

做如下的事情:

df.groupBy('group_id', window('event_time', '1 hour').alias('model_window')) \ 
    .agg(dfcount(lit(1)).alias('values')) 

计算每小时的事件数,但不是每天累计。

有什么想法吗?

编辑: 预期的输出类似于:

    +---------+---------------------------------------------+-------+ 
    |group_id |model_window                                 |values |          
    +---------+---------------------------------------------+-------+ 
    |XXXX     |[2017-10-25 00:00:00.0,2017-10-25 01:00:00.0]| 10    | 
    |XXXX     |[2017-10-25 00:00:00.0,2017-10-25 02:00:00.0]| 17    | 
    |XXXX     |[2017-10-25 00:00:00.0,2017-10-25 03:00:00.0]| 22    | 
    |YYYY     |[2017-10-25 00:00:00.0,2017-10-25 01:00:00.0]| 0     | 
    |YYYY     |[2017-10-25 00:00:00.0,2017-10-25 02:00:00.0]| 1     | 
    |YYYY     |[2017-10-25 00:00:00.0,2017-10-25 03:00:00.0]| 9     | 
    +---------+---------------------------------------------+-------+ 

请您参考如下方法:

want to calculate ... per hour within a day per group_id.

提取数据和时间:

from pyspark.sql.functions import col, count, hour, sum 
 
extended = (df 
  .withColumn("event_time", col("event_time").cast("timestamp")) 
  .withColumn("date", col("event_time").cast("date")) 
  .withColumn("hour", hour(col("event_time")))) 

计算聚合

aggs = extended.groupBy("group_id", "date", "hour").count() 

I want to calculate the rolling count of events

并使用窗口函数:

from pyspark.sql.window import Window 
 
aggs.withColumn( 
    "agg_count",  
    sum("count").over(Window.partitionBy("group_id", "date").orderBy("hour"))) 

要获得 0 的缺失间隔,您必须为每个日期和小时生成引用数据并加入它。

df 定义为:

df = sc.parallelize([ 
    ("XXXX", "2017-10-25 01:47:02.717013"), 
    ("XXXX", "2017-10-25 14:47:25.444979"), 
    ("XXXX", "2017-10-25 14:49:32.21353"), 
    ("YYYY", "2017-10-25 14:50:38.321134"), 
    ("YYYY", "2017-10-25 14:51:12.028447"), 
    ("ZZZZ", "2017-10-25 14:51:24.810688"), 
    ("YYYY", "2017-10-25 14:37:34.241097"), 
    ("ZZZZ", "2017-10-25 14:37:24.427836"), 
    ("XXXX", "2017-10-25 22:37:24.620864"), 
    ("YYYY", "2017-10-25 16:37:24.964614") 
]).toDF(["group_id", "event_time"]) 

结果是

+--------+----------+----+-----+---------+                                       
|group_id|      date|hour|count|agg_count| 
+--------+----------+----+-----+---------+ 
|    XXXX|2017-10-25|   1|    1|        1| 
|    XXXX|2017-10-25|  14|    2|        3| 
|    XXXX|2017-10-25|  22|    1|        4| 
|    ZZZZ|2017-10-25|  14|    2|        2| 
|    YYYY|2017-10-25|  14|    3|        3| 
|    YYYY|2017-10-25|  16|    1|        4| 
+--------+----------+----+-----+---------+