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

基于ID与上一行数据计算并填充DataFrame的Start Value

用Pandas实现分组递推填充Start Value

没问题,我来帮你搞定这个需求!我们需要按ID分组,对每组内的日期行进行递推计算:首日保留初始Start Value,之后每天的Start Value等于前一天的Start Value减去前一天的Payment。下面是具体实现步骤:

1. 构造标准DataFrame

首先把你提供的数据转换成Pandas可处理的格式(补充缺失的列值,非首日的Start Value设为NaN,Payment列补全):

import pandas as pd

data = {
    'ID': [111, 111, 111, 111, 111, 222, 222, 222, 222, 222, 222, 222],
    'Date': ['1/1/2018', '1/2/2018', '1/3/2018', '1/4/2018', '1/5/2018',
             '4/1/2018', '4/2/2018', '4/3/2018', '4/4/2018', '4/5/2018', '4/6/2018', '4/7/2018'],
    'Start Value': [1000, None, None, None, None, 2000, None, None, None, None, None, None],
    'Payment': [0, 100, 500, 400, 0, 200, 100, 700, 0, 0, 1000, 0]
}

df = pd.DataFrame(data)
# 转换日期格式并确保分组内按时间排序(关键!避免计算顺序错误)
df['Date'] = pd.to_datetime(df['Date'])
df = df.sort_values(['ID', 'Date']).reset_index(drop=True)

2. 核心计算逻辑

我们可以用两种方式实现:一种是直观的遍历递推,适合理解;另一种是向量化计算,适合大数据集。

方式一:遍历递推(逻辑清晰)

定义一个分组处理函数,对每个ID组逐行计算:

def fill_start_value(group):
    # 获取组内首日的初始Start Value
    initial_start = group['Start Value'].iloc[0]
    start_values = [initial_start]
    
    # 从第二行开始递推计算
    for i in range(1, len(group)):
        prev_start = start_values[i-1]
        prev_payment = group['Payment'].iloc[i-1]
        current_start = prev_start - prev_payment
        start_values.append(current_start)
    
    group['Start Value'] = start_values
    return group

# 应用到每个ID分组
df_filled = df.groupby('ID', group_keys=False).apply(fill_start_value)

方式二:向量化计算(高效快速)

利用cumsum实现累计求和,避免循环,速度更快:

def fill_start_value_vectorized(group):
    # 计算Payment的累计和,偏移1位(取前序Payment的累计),初始位置填充0
    payment_cumsum = group['Payment'].cumsum().shift(1).fillna(0)
    # 初始值减去前序Payment的累计和
    group['Start Value'] = group['Start Value'].iloc[0] - payment_cumsum
    return group

df_filled = df.groupby('ID', group_keys=False).apply(fill_start_value_vectorized)

3. 查看结果

运行后打印df_filled,会得到填充完成的DataFrame:

ID       Date  Start Value  Payment
0   111 2018-01-01        1000.0        0
1   111 2018-01-02        1000.0      100
2   111 2018-01-03         900.0      500
3   111 2018-01-04         400.0      400
4   111 2018-01-05           0.0        0
5   222 2018-04-01        2000.0      200
6   222 2018-04-02        1800.0      100
7   222 2018-04-03        1700.0      700
8   222 2018-04-04        1000.0        0
9   222 2018-04-05        1000.0        0
10  222 2018-04-06        1000.0     1000
11  222 2018-04-07           0.0        0

注意事项

  • 一定要确保每个ID组内的行是按日期顺序排列的,否则递推计算会出错,所以我们提前做了排序处理。
  • 如果你的原始数据已经是按ID和日期排序的,可以跳过sort_values步骤,但建议保留以避免潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:33:06