我使用pySpark来处理网站访问者数据集,其中每个用户都被分配了一个唯一的标识符。
访问时间戳 | |
---|---|
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|
#+----------+----------+---------------+