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

Spark DataFrame替换skills-specialization后续skills值的问题求助

Spark DataFrame 批量替换后续符合条件的数据

需求说明

将skills-specialization之后的所有连续skills替换为skills-specialization,直到遇到非skills的内容为止。

原始数据

group
skills
skills
skills
skills
skills
skills
skills
skills
skills-specialization
skills
skills
skills
job profile
job description

现有代码

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

# Define the data
data = [("skills",), ("skills",), ("skills",), ("skills",), ("skills",), 
        ("skills",), ("skills",), ("skills",), ("skills-specialization",), 
        ("skills",), ("skills",), ("skills",), ("job profile",), ("job description",)]

# Create a DataFrame named 'df'
df = spark.createDataFrame(data, ["group"])

# Add a new column 'partition' indicating presence of "skills-specialization"
df = df.withColumn("partition", F.when(F.col("group") == "skills-specialization", 1).otherwise(0))

# Assign row numbers within each partition
windowSpec = Window.orderBy(F.monotonically_increasing_id())
df = df.withColumn("row_num", F.row_number().over(windowSpec))

# Create a new column 'replace' to mark rows where "skills" follows "skills-specialization"
df = df.withColumn("replace", F.when((F.col("group") == "skills") & (F.lag(F.col("group")).over(windowSpec) == "skills-specialization"), "skills-specialization").otherwise(F.col("group")))

# Update 'replace' column for all rows after the first "skills"
df = df.withColumn("replace", F.when(F.col("replace") == "skills-specialization", "skills-specialization").otherwise(F.col("replace")))

# Select the updated 'replace' column and drop temporary columns
df = df.select("replace").drop("partition", "row_num")

# Display the DataFrame
df.display()

当前运行结果

replace
skills
skills
skills
skills
skills
skills
skills
skills
skills-specialization
skills-specialization
skills
skills
job profile
job description

预期目标结果

group
skills
skills
skills
skills
skills
skills
skills
skills
skills-specialization
skills-specialization
skills-specialization
skills-specialization
job profile
job description

解决方案

核心思路是通过累积标记识别需要替换的区间:从skills-specialization出现后,直到遇到非skills内容前,所有skills都替换为skills-specialization。

代码实现:

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

data = [("skills",), ("skills",), ("skills",), ("skills",), ("skills",), 
        ("skills",), ("skills",), ("skills",), ("skills-specialization",), 
        ("skills",), ("skills",), ("skills",), ("job profile",), ("job description",)]

df = spark.createDataFrame(data, ["group"])

# 定义窗口:按行顺序保留原始数据顺序
window_spec = Window.orderBy(F.monotonically_increasing_id())

# 1. 创建标记列:遇到skills-specialization则激活标记,遇到非skills且标记已激活时关闭标记,否则继承前一行标记
df = df.withColumn(
    "should_replace",
    F.coalesce(
        F.when(F.col("group") == "skills-specialization", 1),
        F.when((F.col("group") != "skills") & (F.lag("should_replace").over(window_spec) == 1), 0),
        F.lag("should_replace").over(window_spec)
    ).cast("int")
)

# 2. 根据标记替换数据:当标记激活且当前值是skills时,替换为skills-specialization,否则保留原值
df = df.withColumn(
    "group",
    F.when((F.col("should_replace") == 1) & (F.col("group") == "skills"), "skills-specialization")
    .otherwise(F.col("group"))
)

# 3. 清理临时列并展示结果
df = df.drop("should_replace")
df.display()

代码说明

  • should_replace列:用lag函数实现累积标记,激活条件是遇到skills-specialization,关闭条件是遇到非skills的内容。
  • 替换逻辑:仅当标记激活且当前值是skills时执行替换操作,其他情况保留原始值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 02:55:57