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

如何按航班链自定义分组计算Mean Abs Error:先求和再取绝对值

自定义分组下的特殊MAE计算实现

需求说明

需要计算特殊Mean Absolute Error(MAE):先对分组内的fuel_prediction_dev求和,取绝对值后再除以组内有效行数,而非常规的先取绝对值再平均。例如Group1的正确计算方式为:abs(2600-2500-3100+2300)/4 = 175,而非常规的(2600+2500+3100+2300)/4 = 2625。

数据示例

现有预测结果DataFrame(注:原表中Group列不存在,为示例标注用):

Groupflight_date_exact_utcscheduled_arrival_date/time_utctail_number(机尾号)ond_flown(执飞航线)fuel_prediction_dev(燃油预测偏差)fuel_prediction_abs_dev(燃油预测绝对偏差)
108.06.202109.06.2021 08:30Aircraft 1JFK-YYZ26002600
109.06.202109.06.2021 13:35Aircraft 1YYZ-ORD-25002500
109.06.202109.06.2021 19:10Aircraft 1ORD-YYZ-31003100
109.06.202110.06.2021 08:30Aircraft 1YYZ-JFK23002300
212.06.202113.06.2021 08:30Aircraft 1JFK-YYZ-12001200
213.06.202114.06.2021 08:30Aircraft 1YYZ-JFK500500
320.07.202121.07.2021 08:30Aircraft 2JFK-YYZ500500
321.07.202121.07.2021 13:30Aircraft 2YYZ-ORD-23002300
321.07.202121.07.2021 18:55Aircraft 2ORD-YYZ-37003700
321.07.202122.07.2021 08:30Aircraft 2YYZ-JFK500500
423.07.202123.07.2021 18:55Aircraft 2JFK-MIA500500
423.07.202124.07.2021 08:30Aircraft 2MIA-JFK-700700
520.07.202121.07.2021 08:30Aircraft 2JFK-YYZ500500
524.07.202121.07.2021 13:30Aircraft 2YYZ-ORD-23002300
524.07.202121.07.2021 18:55Aircraft 2ORD-YYZ-37003700
5该行缺失但应为Aircraft 2YYZ-JFK无数据无数据

问题难点

  • 无现成分组列,无法直接调用groupby()
  • 同一分组内航班日期可能不同,无法按日期分组
  • 部分行存在数据缺失,需过滤无效数据

分组规则

  • 分组以ond_flown的出发地为JFK作为起始,以目的地为JFK作为结束(首尾行可能缺失)
  • 每组最多4行,通常行数更少
  • 每组属于同一tail_number(机尾号)的连续航班链

实现步骤(Python Pandas)

1. 数据预处理

转换日期时间格式、拆分航线为出发/到达地、按机尾号和到达时间排序以保证航班连续性:

import pandas as pd

# 转换日期时间列为datetime类型(处理格式错误时设为NaN)
df['scheduled_arrival_date/time_utc'] = pd.to_datetime(
    df['scheduled_arrival_date/time_utc'], 
    format='%d.%m.%Y %H:%M', 
    errors='coerce'
)
df['flight_date_exact_utc'] = pd.to_datetime(
    df['flight_date_exact_utc'], 
    format='%d.%m.%Y', 
    errors='coerce'
)

# 拆分航线为出发地(dep)和目的地(arr)
df[['dep', 'arr']] = df['ond_flown'].str.split('-', expand=True)

# 按机尾号和到达时间排序,确保航班链的连续性
df = df.sort_values(
    ['tail_number(机尾号)', 'scheduled_arrival_date/time_utc']
).reset_index(drop=True)

2. 生成分组ID

同一机尾号下,当航班出发地为JFK时标记为新组起点,累加生成唯一分组ID:

# 标记新组起点:当前行出发地为JFK,且与上一行机尾号相同(或为该行机尾号的第一行)
df['is_new_group'] = (df['dep'] == 'JFK') & \
                    (df['tail_number(机尾号)'] == df['tail_number(机尾号)'].shift(1)).ne(True)

# 按机尾号累加生成分组ID
df['group_id'] = df.groupby('tail_number(机尾号)')['is_new_group'].cumsum()

3. 计算自定义MAE

过滤缺失数据后,按机尾号+分组ID分组,求和取绝对值再除以组内有效行数:

# 过滤掉fuel_prediction_dev为空的无效行
valid_df = df.dropna(subset=['fuel_prediction_dev'])

# 分组计算自定义MAE
group_mae = valid_df.groupby(['tail_number(机尾号)', 'group_id']).agg(
    total_dev=('fuel_prediction_dev', 'sum'),  # 组内偏差求和
    valid_row_count=('fuel_prediction_dev', 'count')  # 组内有效行数
).assign(
    custom_mae=lambda x: abs(x['total_dev']) / x['valid_row_count']
).reset_index()

# 查看结果
print(group_mae[['tail_number(机尾号)', 'group_id', 'custom_mae']])

结果验证

运行后Group1的custom_mae将输出175,与需求示例一致;其他分组也会按规则计算出正确的特殊MAE。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:10:25