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

基于PySpark实现Excel依赖前序行的多列计算逻辑

Excel计算逻辑转PySpark代码实现

针对包含A-I列的Excel表格(其中F、G、H、I为固定随机值),以下是对应计算逻辑的PySpark实现,核心处理行与行之间的依赖关系(A、B列依赖前一行数据,C、D、E列依赖当前行的B列)。

实现思路

  • 为数据添加行索引,匹配Excel的行顺序,确保能准确获取前一行数据
  • 使用窗口函数lag()提取前一行的B、C、D、E值,用于计算当前行的A、B
  • 按Excel公式依次计算C、D、E列,再通过迭代处理A、B列的序列依赖

完整代码

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

# 初始化Spark会话
spark = SparkSession.builder.appName("ExcelCalcToPySpark").getOrCreate()

# 模拟示例数据:row_num对应Excel行号,F、G为固定随机值,H、I为冗余列
data = [
    (2, 12.5, 8.3, 45, 67),  # Excel第2行
    (3, 9.1, 10.2, 32, 58),  # Excel第3行
    (4, 7.7, 11.5, 29, 61)   # Excel第4行
]
df = spark.createDataFrame(data, ["row_num", "F", "G", "H", "I"])

# 定义窗口:按行号升序,用于获取前一行数据
window_spec = Window.orderBy("row_num")

# 初始化首行(Excel第2行)的A、B值
df = df.withColumn("B", F.when(F.col("row_num") == 2, 1000).otherwise(None))
df = df.withColumn("A", F.when(F.col("row_num") == 2, None).otherwise(None))

# 计算C、D、E列(依赖当前行B值)
df = df.withColumn("C", F.col("B") * 5 + (100 / 2))
df = df.withColumn("D", F.col("B") * 5 + (10 / 2))
df = df.withColumn("E", F.col("B") * 5 + (1 / 2))

# 迭代处理后续行的A、B计算(解决递归依赖)
while df.filter(F.col("B").isNull()).count() > 0:
    # 获取前一行的历史数据
    df = df.withColumn("prev_B", F.lag("B").over(window_spec))
    df = df.withColumn("prev_C", F.lag("C").over(window_spec))
    df = df.withColumn("prev_D", F.lag("D").over(window_spec))
    df = df.withColumn("prev_E", F.lag("E").over(window_spec))
    
    # 计算当前行A列:F + G + ((前一行C+D+E)/2)
    df = df.withColumn(
        "A",
        F.when(F.col("A").isNull(), F.col("F") + F.col("G") + ((F.col("prev_C") + F.col("prev_D") + F.col("prev_E")) / 2))
        .otherwise(F.col("A"))
    )
    
    # 计算当前行B列:A + (前一行B/2)
    df = df.withColumn(
        "B",
        F.when(F.col("B").isNull(), F.col("A") + (F.col("prev_B") / 2))
        .otherwise(F.col("B"))
    )
    
    # 重新计算当前行的C、D、E列(B值已更新)
    df = df.withColumn("C", F.col("B") * 5 + (100 / 2))
    df = df.withColumn("D", F.col("B") * 5 + (10 / 2))
    df = df.withColumn("E", F.col("B") * 5 + (1 / 2))
    
    # 删除临时辅助列
    df = df.drop("prev_B", "prev_C", "prev_D", "prev_E")

# 按行号排序展示结果
df.orderBy("row_num").show(truncate=False)

# 关闭Spark会话
spark.stop()

代码关键点说明

  • row_num字段模拟Excel的行号,保证数据处理顺序与Excel一致
  • 首行A、B值按Excel规则初始化:A为NULL,B=1000
  • C、D、E列直接映射Excel公式,依赖当前行的B值
  • 循环迭代处理后续行的A、B:由于A依赖前一行的C/D/E,B依赖前一行的B和当前行的A,必须通过迭代填充所有行的空值,直到所有计算完成

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 04:42:54