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

如何在PySpark的df.summary()中添加方差统计?

解决PySpark DataFrame缺少方差统计的问题

PySpark的df.summary()方法默认返回的统计量里确实不包含方差,你可以通过以下两种方式补充方差统计:

方法一:合并summary结果与单独计算的方差

先使用summary()获取已有统计量,再单独计算方差后合并两个结果:

  1. 获取基础统计量
# 指定需要的统计量,避免返回多余内容
summary_df = df.summary("mean", "min", "max", "stddev", "25%", "50%", "75%")
  1. 计算方差并转换格式
from pyspark.sql.functions import variance, col

# 先筛选DataFrame中的数值列
numeric_cols = [c for c in df.columns if df.schema[c].dataType.typeName() in ["integer", "double", "float"]]

# 计算所有数值列的方差
variance_df = df.agg(*[variance(c).alias(c) for c in numeric_cols])

# 转换为和summary_df一致的长格式(统计量名+对应值)
variance_long_df = variance_df.selectExpr(
    f"stack({len(numeric_cols)}, {', '.join([f'\'variance\', `{c}`' for c in numeric_cols])}) as (summary, value)"
)
  1. 合并结果
final_stats_df = summary_df.union(variance_long_df)

方法二:直接用agg方法一次性计算所有统计量

这种方式更直接,无需合并步骤,直接通过聚合函数计算所有需要的统计量:

  1. 定义数值列和需要的统计函数
from pyspark.sql.functions import mean, max, min, stddev, variance, percentile_approx

numeric_cols = [c for c in df.columns if df.schema[c].dataType.typeName() in ["integer", "double", "float"]]

# 构建聚合表达式列表
agg_exprs = []
for col_name in numeric_cols:
    agg_exprs.extend([
        mean(col_name).alias(f"{col_name}_mean"),
        max(col_name).alias(f"{col_name}_max"),
        min(col_name).alias(f"{col_name}_min"),
        stddev(col_name).alias(f"{col_name}_stddev"),
        variance(col_name).alias(f"{col_name}_variance"),
        percentile_approx(col_name, 0.25).alias(f"{col_name}_25%"),
        percentile_approx(col_name, 0.5).alias(f"{col_name}_50%"),
        percentile_approx(col_name, 0.75).alias(f"{col_name}_75%")
    ])
  1. 执行聚合并转换格式(可选)
# 宽格式结果(每列对应一个统计量)
stats_wide_df = df.agg(*agg_exprs)

# 转换为和summary一致的长格式
stack_count = len(numeric_cols) * 8
stack_items = []
for col_name in numeric_cols:
    for stat in ["mean", "max", "min", "stddev", "variance", "25%", "50%", "75%"]:
        stack_items.append(f"'{stat}', `{col_name}_{stat}`")

stats_long_df = stats_wide_df.selectExpr(
    f"stack({stack_count}, {', '.join(stack_items)}) as (summary, value)"
)

两种方法对比:

  • 方法一适合已经习惯使用summary()的场景,只需补充方差即可;
  • 方法二更灵活,能完全自定义需要的统计量,避免额外的合并操作。

内容的提问来源于stack exchange,提问作者IDC7861

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:17:25