我需要先进的蟒蛇熊猫帮助解决我的问题。我有这样一个dataframe,它包含4个字符串列,它们标识项目的层次结构,其余的列遵循以下模式:
文本-期间(例如:“实际2020-08-01")
文本可以是:实际的,预测的t-1或预测t3.期间可以是任何月份:2020年-08-01.例如:“实际的第2020-08-01号”“预测”-“预测-2020年-08-01”“预测T-3 - 2020-08-01”
df.columns
显示为:
['HIERARCHY 1', 'HIERARCHY 2', 'HIERARCHY 3',
'ITEM NUMBER', 'ACTUAL|2020-06-01', 'ACTUAL|2020-07-01',
'ACTUAL|2020-08-01', 'ACTUAL|2020-09-01', 'ACTUAL|2020-10-01',
'ACTUAL|2020-11-01', 'ACTUAL|2020-12-01', 'ACTUAL|2021-01-01',
'ACTUAL|2021-02-01', 'ACTUAL|2021-03-01', 'ACTUAL|2021-04-01',
'ACTUAL|2021-05-01', 'ACTUAL|2021-06-01', 'ACTUAL|2021-07-01',
'ACTUAL|2021-08-01', 'ACTUAL|2021-09-01', 'ACTUAL|2021-10-01',
'FORECAST T-1|2021-01-01', 'FORECAST T-1|2021-08-01',
'FORECAST T-1|2021-09-01', 'FORECAST T-1|2021-10-01',
'FORECAST T-1|2021-11-01', 'FORECAST T-3|2021-03-01',
'FORECAST T-3|2021-10-01', 'FORECAST T-3|2021-11-01',
'FORECAST T-3|2021-12-01', 'FORECAST T-3|2022-01-01',
'FORECAST T-1|2020-07-01', 'FORECAST T-1|2020-08-01',
'FORECAST T-1|2020-09-01', 'FORECAST T-1|2020-10-01',
'FORECAST T-1|2020-11-01', 'FORECAST T-1|2020-12-01',
'FORECAST T-1|2021-02-01', 'FORECAST T-1|2021-03-01',
'FORECAST T-1|2021-04-01', 'FORECAST T-1|2021-05-01',
'FORECAST T-1|2021-06-01', 'FORECAST T-3|2020-09-01',
'FORECAST T-3|2020-10-01', 'FORECAST T-3|2020-11-01',
'FORECAST T-3|2020-12-01', 'FORECAST T-3|2021-01-01',
'FORECAST T-3|2021-02-01', 'FORECAST T-3|2021-04-01',
'FORECAST T-3|2021-05-01', 'FORECAST T-3|2021-06-01',
'FORECAST T-3|2021-07-01', 'FORECAST T-3|2021-08-01'],对于任何时期,我们都可以有:实际的,预测的t-1或预测t3。不能保证他们三个人都在场。也许只有其中一种,例如,在特定的时期,我们只能有:“实际的2020-08-01",”预测的T-1比对2020年-08-01“,但没有一栏显示:”预测T-3 2020-08-01“。

我的目标是实现以下数据:


第一步:
对列名重新排序如下:
df.columns
应该是:实际周期1.实际周期N,其中N是最后一个周期,然后是预测的T1周期1.预测T1周期N,其中N是最后一个周期,最后,预测T-3周期1.预报T-3期N,其中N是最后一个周期
它的顺序应该是:实际的,预测的t-1,最后预测t3.在每个类别中,应从最老时期到最近时期(从左到右)。
第2步:
我想对属于同一时间段的列执行操作。我希望循环遍历列名中的每个期间,对于每个期间,我想看看是否有列:“实际的任何期间(除2020-08-01外)”以及该期间的预测指标,如果有:那么我想计算绝对误差,它将被计算为:
df["ABS ERROR T-1 | 2020-08-01"] = (df["ACTUAL | 2020-08-01"] - df["FORECAST T-1 | 2020-08-01"]).abs()
df["ABS ERROR T-3 | 2020-08-01"] = (df["ACTUAL | 2020-08-01"] - df["FORECAST T-3 | 2020-08-01"]).abs()如果当前期间没有实际情况,则跳过。如果没有预测(T1或T3),那么也跳过周期.
如果至少存在实际和1个预测周期,则计算绝对误差。
然后,将其作为新列放在最后的dataframe上。我有50多个专栏。我不能手动这样做,所以我需要为我的问题找到一个模式。

发布于 2021-12-06 14:08:16
列名中包含日期,这使您的数据难以阅读。我建议对你的数据进行重组,以便将日期作为索引。
假设您从下面的dataframe开始:
HIERARCHY 1 HIERARCHY 2 HIERARCHY 3 ITEM NUMBER ACTUAL|2020-06-01 ... FORECAST T-3|2021-04-01 FORECAST T-3|2021-05-01 FORECAST T-3|2021-06-01 FORECAST T-3|2021-07-01 FORECAST T-3|2021-08-01
0 Level 1 Group A Category 1 Item 1 30 ... 64 91 100 34 87
1 Level 1 Group B Category 1 Item 2 88 ... 20 118 22 97 90
2 Level 2 Group F Category 1 Item 2 91 ... 88 46 116 50 59我将首先拆分列名并添加日期作为索引。这样,您就可以为每个['HIERARCHY 1', 'HIERARCHY 2', 'HIERARCHY 3','ITEM NUMBER', 'date']组合创建几个数据格式。然后,您可以连接这些数据文件:
result_df = []
for col in df.columns:
if '|' in col:
name, date = col.split('|')
df_res = df[['HIERARCHY 1', 'HIERARCHY 2', 'HIERARCHY 3','ITEM NUMBER', col]]
df_res = df_res.rename(columns={col:name})
df_res['date'] = date
result_df.append(df_res)
result = pd.concat(result_df).groupby(['HIERARCHY 1', 'HIERARCHY 2', 'HIERARCHY 3','ITEM NUMBER', 'date']).mean()然后,您可以通过['HIERARCHY 1', 'HIERARCHY 2', 'HIERARCHY 3','ITEM NUMBER', 'date']对连接结果进行分组和聚合,筛选NaN值并计算绝对错误:
result = result[~result['ACTUAL'].isna()]
forecast_avail_filter = result[result.columns[1:]].dropna(how='all').index
result = result.loc[forecast_avail_filter]
for col in result.columns[1:]:
ref = col.strip('FORECAST ')
result['ABS ERR ' + ref] = (result["ACTUAL"] - result[col]).abs()
print(result)输出:
ACTUAL FORECAST T-1 FORECAST T-3 ABS ERR -1 ABS ERR -3
HIERARCHY 1 HIERARCHY 2 HIERARCHY 3 ITEM NUMBER date
Level 1 Group A Category 1 Item 1 2020-07-01 112.0 106.0 NaN 6.0 NaN
2020-08-01 114.0 59.0 NaN 55.0 NaN
2020-09-01 76.0 109.0 99.0 33.0 23.0
2020-10-01 107.0 118.0 73.0 11.0 34.0
2020-11-01 60.0 43.0 35.0 17.0 25.0
2020-12-01 31.0 101.0 24.0 70.0 7.0
2021-01-01 82.0 65.0 50.0 17.0 32.0
2021-02-01 54.0 71.0 111.0 17.0 57.0
2021-03-01 44.0 119.0 97.0 75.0 53.0
2021-04-01 25.0 47.0 64.0 22.0 39.0
2021-05-01 69.0 102.0 91.0 33.0 22.0
2021-06-01 53.0 89.0 100.0 36.0 47.0
2021-07-01 110.0 NaN 34.0 NaN 76.0
2021-08-01 56.0 81.0 87.0 25.0 31.0
2021-09-01 86.0 28.0 NaN 58.0 NaN
2021-10-01 61.0 23.0 79.0 38.0 18.0
Group B Category 1 Item 2 2020-07-01 96.0 99.0 NaN 3.0 NaN
2020-08-01 35.0 24.0 NaN 11.0 NaN
2020-09-01 109.0 106.0 56.0 3.0 53.0
2020-10-01 83.0 104.0 28.0 21.0 55.0
2020-11-01 66.0 45.0 60.0 21.0 6.0
2020-12-01 55.0 89.0 47.0 34.0 8.0
2021-01-01 42.0 93.0 52.0 51.0 10.0
2021-02-01 114.0 21.0 33.0 93.0 81.0
2021-03-01 46.0 80.0 73.0 34.0 27.0
2021-04-01 107.0 37.0 20.0 70.0 87.0
2021-05-01 116.0 76.0 118.0 40.0 2.0
2021-06-01 25.0 65.0 22.0 40.0 3.0
2021-07-01 77.0 NaN 97.0 NaN 20.0
2021-08-01 27.0 57.0 90.0 30.0 63.0
2021-09-01 101.0 115.0 NaN 14.0 NaN
2021-10-01 75.0 43.0 48.0 32.0 27.0
Level 2 Group F Category 1 Item 2 2020-07-01 107.0 62.0 NaN 45.0 NaN
2020-08-01 60.0 27.0 NaN 33.0 NaN
2020-09-01 89.0 22.0 81.0 67.0 8.0
2020-10-01 48.0 25.0 118.0 23.0 70.0
2020-11-01 109.0 87.0 24.0 22.0 85.0
2020-12-01 44.0 21.0 86.0 23.0 42.0
2021-01-01 96.0 30.0 75.0 66.0 21.0
2021-02-01 26.0 65.0 56.0 39.0 30.0
2021-03-01 41.0 93.0 105.0 52.0 64.0
2021-04-01 32.0 53.0 88.0 21.0 56.0
2021-05-01 28.0 38.0 46.0 10.0 18.0
2021-06-01 78.0 67.0 116.0 11.0 38.0
2021-07-01 99.0 NaN 50.0 NaN 49.0
2021-08-01 71.0 114.0 59.0 43.0 12.0
2021-09-01 61.0 82.0 NaN 21.0 NaN
2021-10-01 40.0 36.0 90.0 4.0 50.0https://stackoverflow.com/questions/70243706
复制相似问题