使用PySpark计算不同年份同月的pageviews与visits指标差值
PySpark/SparkSQL 实现同月份年度指标差值计算
两种实现方式均为向量化执行,性能远高于pandas循环遍历的方案:
PySpark DataFrame API 实现
实现逻辑
- 拆分原始
year_month字段得到年份、月份维度,过滤只保留2020、2021两年的数据 - 按年份+月份分组聚合得到各月的pageviews、visits总和
- 按月份关联2020和2021年的聚合结果
- 计算两个指标的年度差值,输出要求字段
代码示例
from pyspark.sql import functions as F # 假设你已将原始数据加载为Spark DataFrame,变量名为df # 1. 拆分年月维度、过滤目标年份 df_process = df.withColumn("year", F.substring("year_month", 1, 4).cast("int")) \ .withColumn("month", F.substring("year_month", 6, 2)) \ .filter(F.col("year").isin(2020, 2021)) # 2. 按年月聚合指标总和 df_month_agg = df_process.groupBy("year", "month") \ .agg( F.sum("pageviews").alias("sum_pv"), F.sum("visits").alias("sum_visits") ) # 3. 拆分2020、2021年的聚合结果后按月份关联 df_2020 = df_month_agg.filter(F.col("year") == 2020).select("month", F.col("sum_pv").alias("pv_2020"), F.col("sum_visits").alias("visits_2020")) df_2021 = df_month_agg.filter(F.col("year") == 2021).select("month", F.col("sum_pv").alias("pv_2021"), F.col("sum_visits").alias("visits_2021")) df_join = df_2021.join(df_2020, on="month", how="left") # 4. 计算差值输出结果,coalesce处理部分月份无对应上年数据的场景 df_result = df_join.select( F.col("month").alias("last_month"), (F.coalesce("pv_2021", F.lit(0)) - F.coalesce("pv_2020", F.lit(0))).alias("diff(pageviews)"), (F.coalesce("visits_2021", F.lit(0)) - F.coalesce("visits_2020", F.lit(0))).alias("diff(visits)") ) # 打印结果 df_result.show()
Spark SQL 实现
如果你习惯SQL语法,可以直接注册临时表后执行SQL查询:
-- 注册原始数据为临时表 CREATE OR REPLACE TEMP VIEW user_behavior_raw AS SELECT * FROM 你的原始数据源; WITH year_month_split AS ( SELECT SUBSTRING(year_month, 1, 4) AS year, SUBSTRING(year_month, 6, 2) AS month, pageviews, visits FROM user_behavior_raw WHERE SUBSTRING(year_month, 1, 4) IN ('2020', '2021') ), month_agg AS ( SELECT year, month, SUM(pageviews) AS sum_pv, SUM(visits) AS sum_visits FROM year_month_split GROUP BY year, month ) SELECT t21.month AS last_month, COALESCE(t21.sum_pv, 0) - COALESCE(t20.sum_pv, 0) AS `diff(pageviews)`, COALESCE(t21.sum_visits, 0) - COALESCE(t20.sum_visits, 0) AS `diff(visits)` FROM month_agg t21 LEFT JOIN month_agg t20 ON t21.month = t20.month AND t20.year = '2020' WHERE t21.year = '2021';
样例数据输出结果
基于你给出的测试数据,运行后得到的结果如下:
| last_month | diff(pageviews) | diff(visits) |
|---|---|---|
| 03 | -4 | 0 |
| 05 | 58 | 0 |
| 08 | -280 | -170 |
内容的提问来源于stack exchange,提问作者set92
相关产品推荐
相关产品推荐

