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

Python Pandas:按ID分组更新参数最新日期值(简单动态规则)

问题与解决方案

问题背景

现有一个按季度日期记录各ID对应参数的DataFrame,初始为随机打乱状态,需先按fab_date和id排序,数据构造代码如下:

import pandas as pd
import numpy as np

np.random.seed(1)
dt_to_fun = pd.DataFrame({
    'fab_date': pd.to_datetime(["2022-01-01", "2022-07-01", "2023-01-01", "2023-07-01",
                                "2022-01-01", "2022-07-01", "2023-01-01", "2023-07-01",
                                "2022-01-01", "2022-07-01", "2023-01-01", "2023-07-01"]),
    'id': ['n_01', 'n_01', 'n_01', 'n_01', 'n_02', 'n_02', 'n_02', 'n_02', 'n_03', 'n_03', 'n_03', 'n_03'],
    'param_01': np.random.choice([10, 20, 30], size=12),
    'param_02': np.random.choice([10, 30, 50], size=12)
})

初始数据如下:

fab_date    id  param_01    param_02
0   2022-01-01  n_01    20  30
1   2022-07-01  n_01    10  50
2   2023-01-01  n_01    10  10
3   2023-07-01  n_01    20  50
4   2022-01-01  n_02    20  30
5   2022-07-01  n_02    10  50
6   2023-01-01  n_02    10  10
7   2023-07-01  n_02    20  10
8   2022-01-01  n_03    10  50
9   2022-07-01  n_03    20  10
10  2023-01-01  n_03    10  30
11  2023-07-01  n_03    30  50

需求:对每个ID,仅更新其最新日期行的所有param*列值,更新规则为:
param(最新日期) = param(最新日期) + param(上一日期) - param(上上个日期)

例如ID n_03的param_02最新值为50,上一值为30,上上个值为10,更新后应为50+30-10=70。期望结果如下:

fab_date    id  param_01    param_02
0   2022-01-01  n_01    20  30
1   2022-07-01  n_01    10  50
2   2023-01-01  n_01    10  10
3   2023-07-01  n_01    20  10
4   2022-01-01  n_02    20  30
5   2022-07-01  n_02    10  50
6   2023-01-01  n_02    10  10
7   2023-07-01  n_02    20  -30
8   2022-01-01  n_03    10  50
9   2022-07-01  n_03    20  10
10  2023-01-01  n_03    10  30
11  2023-07-01  n_03    20  70

解决方案

可以通过以下步骤实现需求:

  • 先按id和fab_date排序,确保每个ID的日期是按顺序排列的:
dt_to_fun = dt_to_fun.sort_values(['id', 'fab_date']).reset_index(drop=True)
  • 筛选出所有param*列,方便后续批量处理:
param_cols = [col for col in dt_to_fun.columns if col.startswith('param_')]
  • 按id分组,计算每个参数的上一日期值(shift(1))和上上个日期值(shift(2)),然后计算更新增量:
# 计算每个param列的更新增量:shift(1) - shift(2)
update_delta = dt_to_fun.groupby('id')[param_cols].shift(1) - dt_to_fun.groupby('id')[param_cols].shift(2)
  • 仅对每个ID的最新行应用更新,通过标记每个组的最后一行来定位目标行:
# 标记每个ID的最新行(最后一行)
is_last_row = dt_to_fun.groupby('id').tail(1).index
# 对最新行的param列加上增量
dt_to_fun.loc[is_last_row, param_cols] += update_delta.loc[is_last_row, param_cols].values

完整代码

import pandas as pd
import numpy as np

np.random.seed(1)
dt_to_fun = pd.DataFrame({
    'fab_date': pd.to_datetime(["2022-01-01", "2022-07-01", "2023-01-01", "2023-07-01",
                                "2022-01-01", "2022-07-01", "2023-01-01", "2023-07-01",
                                "2022-01-01", "2022-07-01", "2023-01-01", "2023-07-01"]),
    'id': ['n_01', 'n_01', 'n_01', 'n_01', 'n_02', 'n_02', 'n_02', 'n_02', 'n_03', 'n_03', 'n_03', 'n_03'],
    'param_01': np.random.choice([10, 20, 30], size=12),
    'param_02': np.random.choice([10, 30, 50], size=12)
})

# 排序
dt_to_fun = dt_to_fun.sort_values(['id', 'fab_date']).reset_index(drop=True)

# 筛选param列
param_cols = [col for col in dt_to_fun.columns if col.startswith('param_')]

# 计算更新增量
update_delta = dt_to_fun.groupby('id')[param_cols].shift(1) - dt_to_fun.groupby('id')[param_cols].shift(2)

# 更新最新行
is_last_row = dt_to_fun.groupby('id').tail(1).index
dt_to_fun.loc[is_last_row, param_cols] += update_delta.loc[is_last_row, param_cols].values

print(dt_to_fun)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 17:47:05