You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在PySpark DataFrame中基于当前日期计算薪资剩余金额?

PySpark解决方案:计算截至当前日期的剩余薪资金额

我来帮你搞定这个需求!核心思路是先确定截至当前日期实际已工作的月份数,再结合总薪资算出累计发放金额,最后得到剩余金额。下面是完整的PySpark实现方案:

核心逻辑梳理

先明确几个关键计算规则:

  • 已工作月份数
    • 若当前日期早于合同起始日(start_date):已工作0个月
    • 若当前日期晚于合同结束日(end_date):已工作满合同总时长(duration)
    • 其他情况:计算start_date到当前日期的月份差,取整数部分(和你例子里的逻辑一致,比如2021-05-03到2022-01-03就是8个月)
  • 每月薪资:总薪资(Total_salary)除以合同总时长(duration)
  • 累计发放金额:已工作月份数 × 每月薪资
  • 剩余金额:总薪资 - 累计发放金额(结果不能为负,若为负则取0)

PySpark代码实现

from pyspark.sql import SparkSession
from pyspark.sql.functions import current_date, months_between, floor, when, col, greatest, lit

# 初始化SparkSession
spark = SparkSession.builder.appName("SalaryRemainingCalculation").getOrCreate()

# 创建样本数据集
data = [
    ("2021-05-03", "2022-05-03", 12, 1200, 400),
    ("2019-01-01", "2023-01-01", 48, 4800, 2300),
    ("2018-01-01", "2020-01-01", 24, 2400, 0),
    ("2020-01-01", "2023-01-01", 36, 3600, 1200),
    ("2024-01-01", "2027-01-01", 36, 3600, 3600)
]

columns = ["start_date", "end_date", "duration", "Total_salary", "original_left_amount"]
df = spark.createDataFrame(data, columns)

# 转换日期类型为PySpark date格式
df = df.withColumn("start_date", col("start_date").cast("date"))
df = df.withColumn("end_date", col("end_date").cast("date"))

# 计算已工作月份数
df = df.withColumn(
    "worked_months",
    when(col("start_date") > current_date(), 0)
    .when(col("end_date") < current_date(), col("duration"))
    .otherwise(floor(months_between(current_date(), col("start_date"))))
)

# 计算每月薪资、累计发放金额、剩余金额
df = df.withColumn("monthly_salary", col("Total_salary") / col("duration"))
df = df.withColumn("paid_amount", col("worked_months") * col("monthly_salary"))
df = df.withColumn("calculated_left_amount", greatest(col("Total_salary") - col("paid_amount"), lit(0)))

# 查看结果(对比原样本的left_amount验证)
df.select(
    "start_date", "end_date", "duration", "Total_salary",
    "original_left_amount", "worked_months", "paid_amount", "calculated_left_amount"
).show(truncate=False)

代码细节解释

  1. 日期转换:先把字符串类型的日期转成PySpark的date类型,确保后续日期计算准确
  2. 已工作月份计算:用when分支处理三种场景,months_between计算两个日期的月份差,floor取整数部分贴合你例子中的逻辑
  3. 薪资计算:通过基础算术运算得到每月薪资和累计发放金额,greatest函数保证剩余金额不会出现负数(比如合同结束后剩余金额强制为0)
  4. 结果验证:把计算出的剩余金额和原样本的left_amount对比,确认逻辑正确性

灵活调整点

如果你的业务对月份计算有更精细的要求(比如跨月不足一个月按比例折算,或者按实际天数计算),可以修改worked_months的计算逻辑,比如替换成基于天数的占比计算。

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

火山引擎 最新活动