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

基于日期差在PySpark DataFrame中创建二元指示列的高效实现

高效实现方案

针对任意行数的场景,推荐使用窗口函数结合条件判断的方案,既适配需求又保证计算效率,以下提供两种可行写法:

写法一:窗口聚合+条件过滤(兼容PySpark全版本)

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

# 定义窗口:按ID分区,date升序,窗口范围从当前行的下一行到分区末尾
window_spec = Window.partitionBy("ID").orderBy("date").rowsBetween(1, Window.unboundedFollowing)

# 计算D列:检查后续行是否存在符合条件的记录
df_result = df.withColumn(
    "D",
    F.max(
        F.when(
            (F.datediff(F.col("date"), F.lag("date").over(Window.partitionBy("ID").orderBy("date"))) < 14) & 
            (F.col("bool") == 1),
            1
        ).otherwise(0)
    ).over(window_spec)
).fillna(0, subset=["D"])  # 最后一行无后续行,填充0

df_result.show()

写法二:exists函数判断(PySpark 3.0+版本支持)

逻辑更直观,直接判断窗口内是否存在符合条件的记录:

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

# 定义窗口:按ID分区,date升序,窗口范围从当前行的下一行到分区末尾
window_spec = Window.partitionBy("ID").orderBy("date").rowsBetween(1, Window.unboundedFollowing)

# 收集后续行的date和bool,用exists判断是否符合条件
df_result = df.withColumn(
    "D",
    F.when(
        F.exists(
            F.collect_list(F.struct("date", "bool")).over(window_spec),
            lambda x: (F.datediff(x.date, F.col("date")) < 14) & (x.bool == 1)
        ),
        1
    ).otherwise(0)
)

df_result.show()

方案优势

  • 无需固定行数,自动适配两周内任意数量的后续行
  • 仅在ID分区内计算,避免跨分区无效运算
  • 窗口函数的计算逻辑由Spark优化引擎处理,性能优于多次调用lag的手动判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 09:53:10