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

PySpark实现固定3行简单移动平均(SMA)并返回空值

PySpark实现固定3行窗口的SMA,不足窗口返回NULL

要实现仅当窗口包含完整3行时计算简单移动平均,否则返回NULL,可以通过窗口函数结合条件判断来处理,以下是几种可行方案:

方案一:SQL方式(基于窗口内计数判断)

修改原SQL语句,新增窗口内的计数逻辑,仅当计数等于3时返回平均值:

select 
    case 
        when count(v1) over (order by id1 rows between 2 preceding and current row) = 3 
        then avg(v1) over (order by id1 rows between 2 preceding and current row) 
        else null 
    end as v1 
from x

执行后结果:

[Row(v1=None), Row(v1=None), Row(v1=10.0), Row(v1=15.0)]

方案二:SQL方式(基于行号判断)

利用row_number()获取当前行的顺序号,当行号≥3时(即存在前2行数据)再计算平均值:

select 
    case 
        when row_number() over (order by id1) >= 3 
        then avg(v1) over (order by id1 rows between 2 preceding and current row) 
        else null 
    end as v1 
from x

方案三:DataFrame API方式

如果习惯用DataFrame操作,写法如下:

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

# 定义3行窗口(前2行+当前行)
window_spec = Window.orderBy("id1").rowsBetween(-2, 0)
# 定义行号窗口
row_num_window = Window.orderBy("id1")

df_result = df.withColumn(
    "v1",
    F.when(
        F.row_number().over(row_num_window) >= 3,
        F.avg("v1").over(window_spec)
    ).otherwise(F.lit(None))
)

df_result.show()

输出结果:

+---+----+
|id1|  v1|
+---+----+
|  1|null|
|  2|null|
|  3|10.0|
|  4|15.0|
+---+----+

原理说明

两种核心思路本质一致:

  • 要么统计当前窗口内的记录数量,确认达到3条后计算平均
  • 要么通过行号判断当前行是否处于第3行及以后,确保存在足够的前置数据

这样就能避免窗口数据不足时计算部分平均,返回符合预期的NULL值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 09:01:18