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

基于日期与分组的tot_value增量计算问题求助

问题

我有一个以date为索引的DataFrame,每个日期对应4个symbol。需要按日期和symbol循环计算:

  • quantity列基于前一日的tot_value
  • tot_value为当日所有symbol的共用值
  • value列随每个symbol变化

当前代码使用shift方法时,无法正确引用前一日的tot_value,而是使用DataFrame初始化时的默认值,但最终tot_value计算正确。恳请修正该循环逻辑。

原代码:

import pandas as pd

# create the dataframe 
data = {'symbol': ['A', 'B', 'C', 'D','A', 'B', 'C', 'D','A', 'B', 'C', 'D','A', 'B', 'C', 'D'],
        'date':['05/06/2024','05/06/2024','05/06/2024','05/06/2024',
                               '05/07/2024','05/07/2024','05/07/2024','05/07/2024',
                               '05/08/2024','05/08/2024','05/08/2024','05/08/2024',
                               '05/09/2024','05/09/2024','05/09/2024','05/09/2024'],
       'tot_value': [1000, 1000, 1000, 1000,1000, 1000, 1000, 1000,1000, 1000, 1000, 1000,1000, 1000, 1000, 1000],
       'mult': [1, 1.1, 1.2, 1.3,1.4, 1.5, 1.6, 1.7,1.8, 1.9, 2, 2.1,2.2, 2.3, 2.4, 2.5],
       'quantity': [0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0],
       'value': [0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0],
       }

df = pd.DataFrame(data)
df.set_index(['date'], inplace = True)
symbols = df['symbol'].unique()

# loop by date index and symbol
for ind in df.index.unique():
    for symbol in symbols:
        df['quantity'][ind] = df['tot_value'][ind].shift(1) * df['mult'][ind]
        df['value'][ind] = df['quantity'][ind] * 5

    g = df.groupby('date')['value'].sum()
    df['tot_value'][ind] = g.sum()
    
df
修正后的代码与逻辑

原代码问题在于:

  1. df['tot_value'][ind].shift(1)无法正确获取前一日的全局tot_value,shift是对列的整体操作,而非单值引用
  2. 循环单个symbol的方式效率低,且容易引发DataFrame赋值警告

修正思路:

  • 用变量单独维护前一日的tot_value,避免依赖DataFrame的shift操作
  • 按时间顺序循环日期,确保每一步都能拿到正确的前置值
  • 批量处理当日所有symbol的计算,再统一更新tot_value

修正后的代码:

import pandas as pd

# 创建初始DataFrame
data = {'symbol': ['A', 'B', 'C', 'D','A', 'B', 'C', 'D','A', 'B', 'C', 'D','A', 'B', 'C', 'D'],
        'date':['05/06/2024','05/06/2024','05/06/2024','05/06/2024',
                               '05/07/2024','05/07/2024','05/07/2024','05/07/2024',
                               '05/08/2024','05/08/2024','05/08/2024','05/08/2024',
                               '05/09/2024','05/09/2024','05/09/2024','05/09/2024'],
       'tot_value': [1000, 1000, 1000, 1000,1000, 1000, 1000, 1000,1000, 1000, 1000, 1000,1000, 1000, 1000, 1000],
       'mult': [1, 1.1, 1.2, 1.3,1.4, 1.5, 1.6, 1.7,1.8, 1.9, 2, 2.1,2.2, 2.3, 2.4, 2.5],
       'quantity': [0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0],
       'value': [0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0,0, 0, 0, 0],
       }

df = pd.DataFrame(data)
# 转换日期格式并排序,确保按时间顺序计算
df['date'] = pd.to_datetime(df['date'], format='%m/%d/%Y')
df.set_index(['date'], inplace=True)
df.sort_index(inplace=True)

# 获取按时间排序的日期列表
dates = df.index.unique().sort_values()
# 初始化前一日的tot_value,取第一天的初始值
prev_tot_value = df.loc[dates[0], 'tot_value'].iloc[0]

for date in dates:
    mask = df.index == date
    if date == dates[0]:
        # 第一天无前置数据,设置quantity和value为NaN
        df.loc[mask, 'quantity'] = pd.NA
        df.loc[mask, 'value'] = pd.NA
    else:
        # 用前一日tot_value计算当日所有symbol的quantity
        df.loc[mask, 'quantity'] = prev_tot_value * df.loc[mask, 'mult']
        # 计算value
        df.loc[mask, 'value'] = df.loc[mask, 'quantity'] * 5
        # 计算当日value总和,更新tot_value
        daily_value_sum = df.loc[mask, 'value'].sum()
        new_tot_value = prev_tot_value + daily_value_sum
        df.loc[mask, 'tot_value'] = new_tot_value
        # 更新前置值,供下一日使用
        prev_tot_value = new_tot_value

# 格式化数字显示(可选)
pd.options.display.float_format = '{:,.0f}'.format
print(df)

关键修正点

  1. 日期排序:确保循环顺序与时间一致,避免计算混乱
  2. 单值维护:用prev_tot_value存储前一天的tot_value,每次循环后更新,保证下一日能正确引用
  3. 批量操作:用loc批量处理当日所有行,避免循环单个symbol,提升效率并避免赋值警告
  4. 首日处理:直接设置首日的quantity和value为NaN,符合预期逻辑

预期结果

datesymboltot_valuemultquantityvalue
2024-05-06A1,0001NaNNaN
2024-05-06B1,0001.1NaNNaN
2024-05-06C1,0001.2NaNNaN
2024-05-06D1,0001.3NaNNaN
2024-05-07A32,0001.41,4007,000
2024-05-07B32,0001.51,5007,500
2024-05-07C32,0001.61,6008,000
2024-05-07D32,0001.71,7008,500
2024-05-08A1,280,0001.857,600288,000
2024-05-08B1,280,0001.960,800304,000
2024-05-08C1,280,000264,000320,000
2024-05-08D1,280,0002.167,200336,000
2024-05-09A61,440,0002.22,816,00014,080,000
2024-05-09B61,440,0002.32,944,00014,720,000
2024-05-09C61,440,0002.43,072,00015,360,000
2024-05-09D61,440,0002.53,200,00016,000,000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:47:34