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

PySpark实现按ID分区、按created_date排序取最后value值

解决Spark中按分区获取最后一个值的问题

你遇到的问题是原窗口函数的默认帧范围限制了last()的取值范围,导致无法获取整个分区的最后一个value。

问题原因

原代码中的窗口Window.partitionBy('id').orderBy('created_date')默认使用的窗口帧是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,也就是说last('value')只会取到当前行及之前的最后一个value,而非整个id分组内最晚created_date对应的value。

解决方案

方案1:修改窗口帧为整个分区

通过指定rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing),让窗口覆盖当前分区的所有行,这样last()就能取到整个分区的最后一个值:

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

w = Window.partitionBy('id').orderBy('created_date').rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing)
df = df.withColumn('last_value', F.last('value').over(w))

方案2:倒序排序后取第一个值

将created_date倒序排列,此时first('value')就等价于原顺序的最后一个值,同样可以确保覆盖整个分区:

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

w = Window.partitionBy('id').orderBy(F.desc('created_date'))
df = df.withColumn('last_value', F.first('value').over(w))

方案3:分组聚合后关联

先通过分组获取每个id的最新created_date对应的value,再关联回原表,这种方式逻辑更直观:

import pyspark.sql.functions as F

# 获取每个id的最新记录对应的value
latest_values = df.groupBy('id').agg(
    F.first('value', ignorenulls=True).over(
        Window.partitionBy('id').orderBy(F.desc('created_date'))
    ).alias('last_value')
).distinct()

# 关联回原数据集
df = df.join(latest_values, on='id', how='left')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:33:15