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

基于简单多数规则聚合DataFrame预测列的技术实现问题

问题

我有一个来自模型预测的pandas DataFrame,示例如下:

import pandas as pd

df = pd.DataFrame({
  'trip-id': [8,8,8,8,8,8,8,8,4,4,4,4,4,4,4,4,4,4,4,4],
 'segment-id': [1,1,1,1,1,1,1,1,0,0,0,0,0,0,5,5,5,5,5,5],
 'true_label': [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
 'prediction': [3, 3, 3, 1, 2, 4, 0, 0, 3, 3, 3, 0, 1, 2, 3, 3, 1, 1, 2, 2]
})

# 输出的DataFrame结构:
#    trip-id  segment-id  true_label  prediction
# 0        8           1           3           3
# 1        8           1           3           3
# 2        8           1           3           3
# 3        8           1           3           1
# 4        8           1           3           2
# 5        8           1           3           4
# 6        8           1           3           0
# 7        8           1           3           0
# 8        4           0           3           3
# 9        4           0           3           3
# 10       4           0           3           3
# 11       4           0           3           0
# 12       4           0           3           1
# 13       4           0           3           2
# 14       4           5           3           3
# 15       4           5           3           3
# 16       4           5           3           1
# 17       4           5           3           1
# 18       4           5           3           2
# 19       4           5           3           2

该数据集包含行程段实例的预测值与真实标签,需要基于以下简单多数规则生成段级预测汇总:

  • 取段内出现次数占简单多数的预测值作为该段的预测结果;
  • 若出现多数值平局,则选取与true_label匹配的值作为段预测结果;
  • 若平局且无匹配真实标签的值,则选取平局值中在DataFrame中最先出现的那个。

当前使用的代码如下:

segments_summary = (
     df['true_label'].eq(df['prediction'])
       .groupby([df['true_label'],df['trip-id'], df['segment-id']]).mean()
       .ge(0.5)
       .groupby(level='true_label').agg(['size','sum'])
       .rename(columns={'size':'total-segments','sum':'correctly-predicted'})\
       .assign(recall = lambda x: round(x['correctly-predicted']/x['total-segments'], 2))
       .reindex(range(5), fill_value='-')
       .reset_index())

运行结果不符合预期:

true_label total-segments correctly-predicted recall
0          0              -                   -      -
1          1              -                   -      -
2          2              -                   -      -
3          3              3                   1   0.33
4          4              -                   -      -

根据规则,3个段都应被正确预测:

  • trip 8, segment 1:3为多数值,应预测为3;
  • trip 4, segment 0:3为多数值,应预测为3;
  • trip 4, segment 5:出现平局,应选取匹配true_label的3作为预测结果。

期望得到如下结果:

true_label total-segments correctly-predicted recall
0          0              -                   -      -
1          1              -                   -      -
2          2              -                   -      -
3          3              3                   3    1.0
4          4              -                   -      -

请帮忙修正代码以得到符合规则的段级预测汇总。

解决方案

原代码的问题在于直接计算段内预测正确的比例并判断是否≥0.5,这不符合自定义的多数规则。需要先按照规则生成每个段的最终预测值,再统计正确数。

修正后的代码如下:

import pandas as pd

def get_segment_prediction(group):
    # 统计每个预测值的出现次数
    pred_counts = group['prediction'].value_counts()
    # 获取最高出现次数
    max_count = pred_counts.max()
    # 筛选出出现次数等于最高次数的候选值
    candidates = pred_counts[pred_counts == max_count].index.tolist()
    
    # 规则2:如果真实标签在候选中,选它
    true_label = group['true_label'].iloc[0]
    if true_label in candidates:
        return true_label
    # 规则3:否则选候选中最先出现的那个
    else:
        for pred in group['prediction']:
            if pred in candidates:
                return pred
    # 规则1:如果只有一个候选(多数),直接返回
    return candidates[0]

# 按true_label、trip-id、segment-id分组,生成每个段的预测结果
segment_predictions = df.groupby(['true_label', 'trip-id', 'segment-id']).apply(get_segment_prediction).reset_index(name='segment_pred')

# 统计每个true_label的总段数和正确预测数
segments_summary = (
    segment_predictions
    .assign(correct=lambda x: x['true_label'] == x['segment_pred'])
    .groupby('true_label')
    .agg(
        total_segments=('segment_pred', 'size'),
        correctly_predicted=('correct', 'sum')
    )
    .assign(recall=lambda x: round(x['correctly_predicted'] / x['total_segments'], 2))
    .reindex(range(5), fill_value='-')
    .rename(columns={
        'total_segments': 'total-segments',
        'correctly_predicted': 'correctly-predicted'
    })
    .reset_index()
)

print(segments_summary)

代码说明:

  1. 自定义函数get_segment_prediction:严格实现三个规则的逻辑:
    • 先统计段内各预测值的出现次数,筛选出出现次数最多的候选值;
    • 检查真实标签是否在候选列表中,是则直接返回;
    • 若不在,遍历原分组的预测值序列,返回第一个出现的候选值;
    • 若只有一个候选(多数情况),直接返回该值。
  2. 分组生成段级预测:按true_label、trip-id、segment-id分组,应用自定义函数得到每个段的最终预测结果。
  3. 统计汇总结果:计算每个true_label对应的总段数、正确预测数和召回率,最后按要求格式填充缺失值并输出。

运行该代码后,将得到期望的结果:

true_label total-segments correctly-predicted recall
0          0              -                   -      -
1          1              -                   -      -
2          2              -                   -      -
3          3              3                   3    1.0
4          4              -                   -      -

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:22:37