Python Pandas:使用按 id 分组的简单动态更新参数的最后日期值

问题描述 投票:0回答:1

这是一个数据框,其中包含一些定期季度日期的每个 id 的参数。它最初是随机打乱的,但是,首先,假设它是按 fab_date 和 id 排序的。

import pandas as pd
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
    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_01(最后日期)= param_01(最后日期)+ param_01(-1日期)- param_01(-2日期) 例如,id n_03 param_02 的最后一个值为 50,前一个值为 30,前两次值为 10,因此结果应为 50 + 30 - 10 = 70。每个 id 和所有 param* 列都相同。仅应更新每个 ID 具有最后日期的行中的参数。

结果表应该是这样的:

dt_to_fun
    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

我尝试过 applymap、shift 等,但无法弄清楚这一切应该如何协同工作。将不胜感激任何帮助。

python pandas dataframe date shift
1个回答
0
投票

IIUC,使用自定义

groupby.transform
diff
shift
:

cols = ['param_01', 'param_02']

dt_to_fun.loc[~dt_to_fun['id'].duplicated(keep='last'), cols] = dt_to_fun.groupby('id')[cols].transform(lambda x: x.diff().shift()).add(dt_to_fun[cols])

输出:

     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
© www.soinside.com 2019 - 2024. All rights reserved.