这是一个数据框,其中包含一些定期季度日期的每个 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 等,但无法弄清楚这一切应该如何协同工作。将不胜感激任何帮助。
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