You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark计算各列最大百分比变化及对应发生年份

需求实现:获取DataFrame各列最大百分比变化值及对应年份

原PySpark代码

# 透视后重命名列
new_column_names = ["Year"] + [col_name.replace(" ", "_") for col_name in pivot_table.columns[1:]]
pivot_table = pivot_table.toDF(*new_column_names)

# 任务4:计算百分比变化
percentage_cols = pivot_table.columns[1:]  # 排除"Year"列
window_spec = Window.orderBy("Year")
print(pivot_table.columns)
pivot_table = pivot_table.drop('Other_purchases_and_operating_expenses')

# 循环计算百分比变化
for col_name in percentage_cols:
    pivot_table = pivot_table.withColumn(f"{col_name}_lag", lag(col(col_name)).over(window_spec))
    pivot_table = pivot_table.withColumn(f"{col_name}_change", (col(col_name) - col(f"{col_name}_lag")) / col(f"{col_name}_lag") * 100)
    pivot_table = pivot_table.drop(f"{col_name}_lag")
    pivot_table = pivot_table.drop(f"{col_name}")

原代码输出

year column ,variablenames column 3

实现方案

基于现有代码的输出结果,我们可以通过窗口函数和聚合操作,快速获取每列的最大百分比变化值及对应年份,具体代码如下:

from pyspark.sql import functions as F
from pyspark.sql.window import Window

# 收集所有百分比变化列(列名以_change结尾)
change_cols = [col for col in pivot_table.columns if col.endswith("_change")]

# 构建聚合表达式:同时获取每个变化列的最大值和对应年份
agg_exprs = []
for col in change_cols:
    # 计算当前列的最大百分比变化值
    max_change = F.max(col).alias(f"max_{col}")
    # 获取该最大值对应的年份(按变化值降序取第一行的年份)
    corresponding_year = F.first("Year", ignorenulls=True).over(
        Window.partitionBy().orderBy(F.desc(col))
    ).alias(f"year_of_max_{col}")
    agg_exprs.extend([max_change, corresponding_year])

# 执行聚合并获取结果
max_change_result = pivot_table.select(*agg_exprs).limit(1)

# 展示最终结果
max_change_result.show(truncate=False)

代码说明

  1. 筛选变化列:通过列名后缀_change识别所有百分比变化字段,避免手动指定列名。
  2. 聚合逻辑:
    • 用F.max()计算每列的最大百分比变化值,并重命名字段以明确含义。
    • 全局窗口按变化值降序排序,取第一行的年份作为最大值对应的发生年份;ignorenulls=True会自动跳过空值行(比如第一年无对比数据生成的null)。
  3. 结果输出:limit(1)确保只返回一行全局聚合结果,show(truncate=False)避免年份或数值被截断。

补充说明

如果某列存在多个年份有相同的最大百分比变化值,上述代码会返回最早出现的年份。若要获取所有对应年份,可将first替换为collect_list,示例如下:

corresponding_year = F.collect_list("Year").over(
    Window.partitionBy().orderBy(F.desc(col))
).alias(f"years_of_max_{col}")

内容的提问来源于stack exchange,提问作者sara ali khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:26:12