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

Python中DataFrame扣除百分比的累计总额非迭代实现求助

问题

需要在Python中实现累计总额(running total)计算:现有DataFrame,初始值为100,从之前的累计值中扣除take_profit列的百分比数值,维持累计总额。目前仅能通过迭代行实现,希望用向量化方法替代,但尝试的代码逻辑出错,存在自引用问题。

当前尝试的代码:

df = df[['trade_long','close_long','active_trade','take_profit']]

df['current_trade_size'] = 0 
df.loc[df['trade_long'], 'current_trade_size'] = 100
df.loc[df['close_long'], 'current_trade_size'] = 0
df['trade_ramainder'] = (1 - (df['take_profit']/100))
df['previous_trade_size'] = df['current_trade_size'].shift(1)
df['current_trade_size'] =  df['previous_trade_size'] * df['trade_ramainder']

当前输出:

Datetrade_longclose_longactive_tradetake_profitcurrent_trade_sizetrade_ramainderprevious_trade_size
2020-01-07TrueFalseTrue0.00NaN1.00NaN
2020-01-08FalseFalseTrue0.00100.001.00100.0
2020-01-09FalseFalseTrue0.680.000.990.0
2020-01-10TrueFalseTrue0.000.001.000.0
2020-01-11FalseFalseTrue0.6999.300.99100.0
2020-01-12TrueFalseTrue0.000.001.000.0
2020-01-13FalseFalseTrue0.00100.001.00100.0

期望输出:

Datetrade_longclose_longactive_tradetake_profitcurrent_trade_size
2020-01-07TrueFalseTrue0.00100.00
2020-01-08FalseFalseTrue0.00100.00
2020-01-09FalseFalseTrue0.6899.32
2020-01-10TrueFalseTrue0.00100.00
2020-01-11FalseFalseTrue0.6998.63
2020-01-12TrueFalseTrue0.00100.00
2020-01-13FalseFalseTrue0.00100.00
解决方案

你的核心问题是用shift无法实现实时自引用计算——shift只能取原始列的前一行值,无法获取计算后的实时值。用分组累计乘积可以实现完全向量化的计算,无需迭代。

实现步骤

  1. 标记重置分组:每当trade_long为True时,开启一个新的计算分组,自然分隔每次重置为100的逻辑。
  2. 计算留存比例:将take_profit转换为每天的资金留存比例1 - take_profit/100。
  3. 分组计算累计乘积:对每个分组内的留存比例计算累计乘积,再乘以初始值100,得到当天的累计总额。
  4. 处理close_long重置:如果close_long触发时需要将数值置0,最后单独修正即可。

完整代码

df = df[['trade_long','close_long','active_trade','take_profit']]

# 1. 创建分组标识:trade_long为True时分组编号递增
df['group'] = df['trade_long'].cumsum()
# 2. 计算每天的资金留存比例
df['trade_remainder'] = 1 - df['take_profit'] / 100
# 3. 分组计算累计乘积,再乘以初始值100
df['current_trade_size'] = df.groupby('group')['trade_remainder'].cumprod() * 100
# 4. 处理close_long的重置逻辑(若需要)
df.loc[df['close_long'], 'current_trade_size'] = 0
# 可选:删除中间辅助列,保留需要的字段
df = df.drop(columns=['group', 'trade_remainder'])

逻辑验证

运行后结果将完全匹配你的期望:

  • 2020-01-07:trade_long=True开启分组1,累计乘积为1,1*100=100
  • 2020-01-08:同一分组,留存比例1,累计乘积1*1=1,1*100=100
  • 2020-01-09:同一分组,留存比例1-0.68/100=0.9932,累计乘积1*0.9932=0.9932,0.9932*100=99.32
  • 2020-01-10:trade_long=True开启分组2,重置为100
  • 后续日期按同样逻辑计算,每次trade_long触发都会重置分组,重新开始累计

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 18:54:52