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

如何在Pandas中将多年合计数据按规则分摊到各对应年度?

Pandas数据分摊转换实现方案

首先从示例可推导分摊规则如下:

  • 单个项目的年度基准分摊额 = 项目总金额 ÷ 项目时长
  • 项目覆盖的年份范围为:从开始年起,到「开始年 + 时长向下取整」的年份为止
  • 覆盖范围内前N个完整年度(N=时长向下取整)每年分摊全额基准额,若时长存在小数部分,最后一年分摊 小数比例 × 基准额
  • 同个项目同一年度存在多个分摊记录时,金额合并求和
  • 最终金额格式为带$符号的千分位格式

完整实现代码

import pandas as pd
import numpy as np

# 1. 构造原始数据集
raw_data = {
    "Program": ["a", "a", "b"],
    "Start year": [2021, 2022, 2020],
    "Duration": [2, 3, 2.5],
    "Total amount": ["$30000", "$3000", "$15000"]
}
df = pd.DataFrame(raw_data)

# 2. 预处理数据:转换金额为数值,计算年度基准分摊额
df["total_num"] = df["Total amount"].str.replace("$", "").astype(int)
df["annual_base"] = df["total_num"] / df["Duration"]

# 3. 按行展开生成各年度分摊记录
split_rows = []
for _, row in df.iterrows():
    prog = row["Program"]
    start_y = row["Start year"]
    dur = row["Duration"]
    base = row["annual_base"]
    full_years = int(np.floor(dur))
    remain = dur - full_years
    
    # 处理完整年份的分摊
    for i in range(full_years):
        split_rows.append({
            "Program": prog,
            "Year": start_y + i,
            "Annual amount": base
        })
    # 处理剩余不足一年的部分
    if remain > 0:
        split_rows.append({
            "Program": prog,
            "Year": start_y + full_years,
            "Annual amount": base * remain
        })

# 4. 合并记录,按项目和年份分组求和
res_df = pd.DataFrame(split_rows).groupby(["Program", "Year"], as_index=False)["Annual amount"].sum()

# 5. 格式化金额为要求的字符串格式
res_df["Annual amount"] = res_df["Annual amount"].apply(lambda x: f"${x:,.0f}")

输出结果

运行上述代码后得到的结果和目标格式完全一致:

ProgramYearAnnual amount
a2021$15,000
a2022$16,000
a2023$1,000
a2024$1,000
b2020$6,000
b2021$6,000
b2022$3,000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:15:06