PySpark中mean结合groupBy计算结果全为NaN的问题排查
问题原因及解决方案
你的mean_change1出现全NaN的核心原因分两种情况:
1. 2021-07-30的均值必然为NaN
该日期是每个ID的第一条记录,通过lag(1)窗口函数无法获取到前一个时间点的value1,因此previous_value1全为null,计算change1 = value1 - previous_value1后结果也全为null,对全null列求均值自然得到NaN。
2. 2022-12-31和2023-04-30的均值理论上不应为NaN
你的数据中:
- 2021年的
value1无NaN值,2022年仅有3个NaN,因此2022年有97个ID的change1是有效数值(当前value1- 2021年value1) - 2023年的
value1全为非NaN,仅3个ID因2022年value1为NaN导致change1为null,其余97个是有效数值
如果这两个日期的均值也显示为NaN,大概率是以下问题:
- 日期列类型异常:Spark创建DataFrame时,若
date列未被识别为日期/时间戳类型,窗口orderBy会排序混乱,导致lag(1)取到的不是前一个日期的值。可以通过df.printSchema()确认,若类型不对,显式转换:df = df.withColumn("date", F.to_date("date")) - 隐性null值干扰:虽然pandas的NaN会被转为Spark的null,但如果数据中存在其他隐性空值,可能导致更多
change1为null。可以先查看有效数据:df.select("date", "change1").filter(F.isnotnull("change1")).show(5)
修复方案
- 过滤无意义的初始日期数据(如果不需要2021年的均值):
mean_df = df.filter(df.date != "2021-07-30").groupBy("date").agg(F.mean("change1").alias("mean_change1")) - 显式处理null值(若需要保留所有日期):
# 给change1的null值设默认值0(注意:这会拉低均值,仅适合业务允许的场景) df = df.withColumn("change1", F.coalesce(df.change1, F.lit(0))) mean_df = df.groupBy("date").agg(F.mean("change1").alias("mean_change1")) - 确保窗口排序正确:确认
date列类型为日期/时间戳,窗口定义保持partitionBy("ID").orderBy("date")即可。
内容的提问来源于stack exchange,提问作者Henri
相关产品推荐
相关产品推荐

