如何有效地计算所有日期组合之间的不同值



我使用pySpark来处理网站访问者数据集,其中每个用户都被分配了一个唯一的标识符。

用户id
访问时间戳
2022-01-01 10:23:44.123456 aaa
2022-01-02 11:22:44.123456 aaa
2022-01-01 11:00:44.123456 bbb
2022-01-01 12:22:44.123456 bbb
2022-01-05 13:23:44.123456 abc
2022-01-03 14:22:44.123456 ccc
2022-01-04 10:23:44.123456 ddd
2022-01-01 11:22:44.123456 eee

我正在寻找一种有效的方法来计算不同用户ID的数量所有可能的日期组合

所有可能的日期组合意味着你几乎在进行交叉联接,这是无效的。也许你可以考虑使用累积计数?


使用此输入数据帧:

from pyspark.sql import functions as F
df = spark.createDataFrame([
("2022-01-01 10:23:44.123456", "aaa"), ("2022-01-02 11:22:44.123456", "aaa"),
("2022-01-01 11:00:44.123456", "bbb"), ("2022-01-01 12:22:44.123456", "bbb"),
("2022-01-05 13:23:44.123456", "abc"), ("2022-01-03 14:22:44.123456", "ccc"),
("2022-01-04 10:23:44.123456", "ddd"), ("2022-01-01 11:22:44.123456", "eee"),
], ["visit_timestamp", "user_id"])
df = df.withColumn("visit_date", F.to_date("visit_timestamp", "yyyy-MM-dd HH:mm:ss.SSSSSS"))

首先,获取不同的日期,并使用自联接来获取所有日期组合:

dates_df = df.selectExpr("visit_date as start_date").distinct().join(
df.selectExpr("visit_date as end_date").distinct(),
F.col("start_date") <= F.col("end_date"),
"left"
)

现在,加入具有原始数据帧的dates_df,并按计数分组:

result = dates_df.join(
df,
(F.col("visit_date") >= F.col("start_date")) & (F.col("visit_date") <= F.col("end_date")),
"left"
).groupBy("start_date", "end_date").agg(
F.count_distinct("user_id").alias("unique_visitors")
).orderBy("start_date", "end_date")
result.show()
#+----------+----------+---------------+
#|start_date|  end_date|unique_visitors|
#+----------+----------+---------------+
#|2022-01-01|2022-01-01|              3|
#|2022-01-01|2022-01-02|              3|
#|2022-01-01|2022-01-03|              4|
#|2022-01-01|2022-01-04|              5|
#|2022-01-01|2022-01-05|              6|
#|2022-01-02|2022-01-02|              1|
#|2022-01-02|2022-01-03|              2|
#|2022-01-02|2022-01-04|              3|
#|2022-01-02|2022-01-05|              4|
#|2022-01-03|2022-01-03|              1|
#|2022-01-03|2022-01-04|              2|
#|2022-01-03|2022-01-05|              3|
#|2022-01-04|2022-01-04|              1|
#|2022-01-04|2022-01-05|              2|
#|2022-01-05|2022-01-05|              1|
#+----------+----------+---------------+

最新更新