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

基于月度限额的部门预算月度分配计算问题(Python Pandas)

问题分析

你的代码只填充第一个NaN的原因是:Pandas的列赋值是一次性计算,无法迭代更新AMT_ALLOC_MONTH列的状态。当你第一次计算时,只有第一个NaN被填充,但后续行的cumsum仍基于原始的NaN值,ffill会直接复制第一个填充值,导致后续分配额重复,无法正确计算剩余预算。

解决方案

下面提供两种高效的实现方式,前提是你的DataFrame已按DEPT和月份列(比如MONTH)排序,确保月份顺序正确。

方法1:分组循环计算(直观易维护)

通过groupby对每个部门单独处理,逐行计算剩余预算并分配金额:

import pandas as pd

# 确保数据按部门和月份排序(替换MONTH为你的月份列名)
table = table.sort_values(['DEPT', 'MONTH'])

def calculate_monthly_alloc(group):
    # 获取部门总预算和月度限额(假设每个部门的AMT_TOTAL/LIMIT_MONTH是固定值)
    total_budget = group['AMT_TOTAL'].iloc[0]
    monthly_limit = group['LIMIT_MONTH'].iloc[0]
    
    remaining = total_budget
    allocations = []
    
    for _ in range(len(group)):
        if remaining <= 0:
            allocations.append(0.0)
        else:
            current_alloc = min(remaining, monthly_limit)
            allocations.append(current_alloc)
            remaining -= current_alloc
    
    group['AMT_ALLOC_MONTH'] = allocations
    return group

# 应用到每个部门
table = table.groupby('DEPT', group_keys=False).apply(calculate_monthly_alloc)

方法2:向量化计算(高性能,适合大数据量)

避免循环,用NumPy数组批量计算分配额,效率更高:

import pandas as pd
import numpy as np

table = table.sort_values(['DEPT', 'MONTH'])

def calculate_alloc_vectorized(group):
    total_budget = group['AMT_TOTAL'].iloc[0]
    monthly_limit = group['LIMIT_MONTH'].iloc[0]
    num_months = len(group)
    
    # 计算需要多少个整月才能用完大部分预算
    full_months = int(total_budget // monthly_limit)
    remaining_amount = total_budget % monthly_limit
    
    # 初始化分配数组,默认全为月度限额
    allocations = np.full(num_months, monthly_limit)
    
    # 处理剩余预算和超出月份的情况
    if full_months < num_months:
        if remaining_amount > 0:
            # 第full_months+1个月分配剩余预算,之后为0
            allocations[full_months] = remaining_amount
            allocations[full_months+1:] = 0.0
        else:
            # 刚好整除,第full_months个月是最后一笔,之后为0
            allocations[full_months:] = 0.0
    
    group['AMT_ALLOC_MONTH'] = allocations
    return group

table = table.groupby('DEPT', group_keys=False).apply(calculate_alloc_vectorized)
关键说明
  • 必须确保数据按DEPT和月份排序,否则分配顺序会出错;
  • 假设每个部门的AMT_TOTAL和LIMIT_MONTH是固定值(同一部门所有行的这两个值相同),如果你的数据中同一部门的这两个值有变化,需要调整函数逻辑(比如取每行的LIMIT_MONTH);
  • 两种方法都会覆盖原AMT_ALLOC_MONTH列的NaN值,直接生成符合规则的分配额。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:25:34