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

如何在PySpark DataFrame的population列中将0替换为中位数?

在PySpark中将DataFrame列的0值替换为中位数

方法一:先计算中位数再替换(简单直观)

先算出目标列的中位数,再用when/otherwise逻辑替换0值。PySpark里推荐用approxQuantile计算中位数,适合大数据场景,效率更高:

1. 计算中位数

  • 包含0值的中位数:
from pyspark.sql import functions as F

# 计算population列的近似中位数,相对误差设为0.01(可根据需求调整精度)
median_val = df.approxQuantile("population", [0.5], 0.01)[0]
  • 排除0值的中位数(如果需要基于非0数据计算):
median_val = df.filter(F.col("population") != 0).approxQuantile("population", [0.5], 0.01)[0]

2. 替换0值

# 将population列中的0替换为中位数
df_updated = df.withColumn(
    "population",
    F.when(F.col("population") == 0, median_val).otherwise(F.col("population"))
)

方法二:聚合关联替换(减少数据扫描次数)

针对大数据集,可通过聚合计算中位数后关联原表,避免多次扫描数据:

# 计算中位数并生成临时DataFrame
median_df = df.select(F.percentile_approx("population", 0.5, 0.01).alias("median_pop"))

# 关联原表并替换0值
df_updated = df.crossJoin(median_df).withColumn(
    "population",
    F.when(F.col("population") == 0, F.col("median_pop")).otherwise(F.col("population"))
).drop("median_pop")

补充:计算精确中位数(小数据集适用)

如果需要精确中位数而非近似值,可使用窗口函数实现(数据量大时效率较低):

from pyspark.sql.window import Window

# 基于非0数据计算精确中位数
window = Window.orderBy("population")
df_with_stats = df.filter(F.col("population") != 0).withColumn(
    "rank", F.row_number().over(window)
).withColumn(
    "total_count", F.count("population").over(Window.partitionBy())
)

# 取中间位置的平均值(兼容偶数/奇数数据量)
median_val = df_with_stats.filter(
    (F.col("rank") == (F.col("total_count") + 1)/2) | 
    (F.col("rank") == (F.col("total_count")/2) + 1)
).select(F.avg("population")).first()[0]

# 替换0值
df_updated = df.withColumn(
    "population",
    F.when(F.col("population") == 0, median_val).otherwise(F.col("population"))
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:22:53