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

Python Pandas:基于累计求和从DataFrame中扣除对应金额的实现

解决方案

实现思路

要完成按name匹配、从小金额开始扣除amount_paid的需求,核心是先对每组数据排序并计算累计金额,结合可扣除额度判断每行剩余值,最后恢复原数据的行顺序。

完整代码

import pandas as pd

# 初始化输入数据
df1 = pd.DataFrame({'name': ['virat', 'virat', 'virat', 'virat', 'virat', 'rohit', 'rohit'], 
                    'amount': [1000, 500, 200, 500, 150, 120, 100]})
df2 = pd.DataFrame({'name': ['virat','rohit'], 'amount_paid': [1400, 200]})

# 1. 保留原索引,按name分组后对amount升序排序(确保从小金额开始扣除)
df_sorted = df1.reset_index().sort_values(['name', 'amount'])

# 2. 计算每组内的累计金额,用于判断扣除进度
df_sorted['cum_amount'] = df_sorted.groupby('name')['amount'].cumsum()

# 3. 关联每个name对应的可扣除额度
df_merged = df_sorted.merge(df2, on='name', how='left')

# 4. 计算每行的剩余金额
def get_remaining(row):
    if row['cum_amount'] <= row['amount_paid']:
        return 0
    elif row['cum_amount'] - row['amount'] >= row['amount_paid']:
        return row['amount']
    else:
        return row['cum_amount'] - row['amount_paid']

df_merged['remaining_amount'] = df_merged.apply(get_remaining, axis=1)

# 5. 恢复原数据的行顺序,整理输出格式
result = df_merged.set_index('index').sort_index()[['name', 'remaining_amount']].rename(columns={'remaining_amount': 'amount'})

print(result)

代码分步说明

  1. 排序并保留原索引:用reset_index()记录原行号,后续用于恢复顺序;按name分组、amount升序排序,保证优先扣除小金额。
  2. 计算累计金额:通过groupby+cumsum得到每组内的累计金额,快速判断当前扣除到哪一行。
  3. 关联可扣除额度:用merge把df2中每个name对应的amount_paid匹配到数据里。
  4. 判断剩余金额:
    • 累计金额≤可扣除额度:当前金额全扣完,剩余0
    • 累计金额减去当前金额仍≥可扣除额度:当前金额完全没被扣除,保留原数
    • 中间情况:剩余金额=累计金额-可扣除额度(扣除部分后的剩余)
  5. 恢复原顺序:按原索引排序,得到和输入df1一致的行顺序,最后调整列名得到目标输出。

最终输出

name  amount
0  virat       0
1  virat     100
2  virat     200
3  virat     500
4  virat     150
5  rohit       0
6  rohit      20

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 19:47:37