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

Spark基于多列lag条件识别字段变动生成row_number的实现问题

实现方案

你需要的是连续相同字段组内的序列生成,直接用row_number()、dense_rank()按三个字段分区无法满足需求,因为普通分区会把所有同值行归为同一组,不区分是否连续。我们可以通过「打变化标记→累加生成组ID→组内生成序号」的逻辑实现,完整代码如下:

from pyspark.sql import Window
from pyspark.sql.functions import col, lag, sum, row_number, when, monotonically_increasing_id

# 先添加自增ID作为排序依据,保证行顺序和输入一致,避免分布式环境下顺序错乱
df = df.withColumn("sort_id", monotonically_increasing_id())

# 1. 定义基础窗口:按account分区,按输入顺序排序,用于对比相邻行的字段差异
base_window = Window.partitionBy("account").orderBy("sort_id")

# 2. 标记当前行和上一行的三个字段是否发生变化,变化则打1,第一行默认打1
df = df.withColumn("is_change", 
    when(
        (lag("account", 1).over(base_window) != col("account")) |
        (lag("name", 1).over(base_window) != col("name")) |
        (lag("type", 1).over(base_window) != col("type")) |
        (lag("account", 1).over(base_window).isNull()),
        1
    ).otherwise(0)
)

# 3. 对变化标记做累加,相同连续组的累加值相同,即为组ID
group_window = Window.partitionBy("account").orderBy("sort_id").rowsBetween(Window.unboundedPreceding, 0)
df = df.withColumn("group_id", sum("is_change").over(group_window))

# 4. 按组ID分区,组内按顺序生成行号,即为预期结果
rn_window = Window.partitionBy("account", "group_id").orderBy("sort_id")
df = df.withColumn("row_number", row_number().over(rn_window))

# 输出结果,可删除中间字段
df.select("Event_date", "account", "name", "type", "row_number").show()

运行后输出结果和你给出的预期完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 02:36:04