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)
代码分步说明
- 排序并保留原索引:用
reset_index()记录原行号,后续用于恢复顺序;按name分组、amount升序排序,保证优先扣除小金额。 - 计算累计金额:通过
groupby+cumsum得到每组内的累计金额,快速判断当前扣除到哪一行。 - 关联可扣除额度:用
merge把df2中每个name对应的amount_paid匹配到数据里。 - 判断剩余金额:
- 累计金额≤可扣除额度:当前金额全扣完,剩余0
- 累计金额减去当前金额仍≥可扣除额度:当前金额完全没被扣除,保留原数
- 中间情况:剩余金额=累计金额-可扣除额度(扣除部分后的剩余)
- 恢复原顺序:按原索引排序,得到和输入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
相关产品推荐
相关产品推荐

