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

如何用Pandas/Numpy在分组内将每行数据追加到组内所有行?

赛马数据集行转列分组处理问题

我有一个按raceId分组的赛马数据集,单场比赛的数据示例如下:

data_orig = {
    'meetingId': [178515] * 6,
    'raceId': [879507] * 6,
    'horseId': [90001, 90002, 90003, 90004, 90005, 90006],
    'position': [1, 2, 3, 4, 5, 6],
    'weight': [51, 52, 53, 54, 55, 56],
}

需要将组内每行的马匹专属数据追加到组内的每一行,预期结果如下:

data_new = {
    'meetingId': [178515] * 6,
    'raceId': [879507] * 6,
    'horseId_a':[90001, 90002, 90003, 90004, 90005, 90006],
    'position_a':[1, 2, 3, 4, 5, 6],
    'weight_a':[51, 52, 53, 54, 55, 56],
    'horseId_b':[90002, 90003, 90004, 90005, 90006, 90001],
    'position_b':[2, 3, 4, 5, 6, 1],
    'weight_b':[52, 53, 54, 55, 56, 51],
    'horseId_c':[90003, 90004, 90005, 90006, 90001, 90002],
    'position_c':[3, 4, 5, 6, 1, 2],
    'weight_c':[53, 54, 55, 56, 51, 52],
    'horseId_d':[90004, 90005, 90006, 90001, 90002, 90003],
    'position_d':[4, 5, 6, 1, 2, 3],
    'weight_d':[54, 55, 56, 51, 52, 53],
    'horseId_e':[90005, 90006, 90001, 90002, 90003, 90004],
    'position_e':[5, 6, 1, 2, 3, 4],
    'weight_e':[55, 56, 51, 52, 53, 54,],
    'horseId_f':[90006, 90001, 90002, 90003, 90004, 90005],
    'position_f':[6, 1, 2, 3, 4, 5],
    'weight_f':[56, 51, 52, 53, 54, 55],
}

我尝试了以下代码但未成功:

data_orig_df = pd.DataFrame(data_orig)
new_df = pd.DataFrame()
for index, row_i in data_orig_df.iterrows():
    horseId = row_i['horseId']
    row_new = row_i.copy()
    for index, row_j in race_df.iterrows():
        if row_j['horseId']:
            continue
        row_new = pd.merge(row_new, row_j[getHorseSpecificCols()], suffixes=('', row_j['position']))
    new_df = pd.concat([new_df, row_new], axis=1)

解决方案

核心思路是对每组内的马匹数据进行循环移位,生成对应后缀的列后合并到原数据中,具体实现代码如下:

import pandas as pd

# 原始数据转DataFrame
df = pd.DataFrame(data_orig)

# 定义需要处理的马匹专属列
horse_cols = ['horseId', 'position', 'weight']
# 生成后缀列表(对应6匹马的后缀a到f)
suffixes = ['a', 'b', 'c', 'd', 'e', 'f']

# 按raceId分组处理(多场比赛时自动独立处理每组)
def process_group(g):
    # 保留原始赛事标识列
    result = g[['meetingId', 'raceId']].copy()
    # 循环生成每一组移位后的列
    for i, suffix in enumerate(suffixes):
        # 循环移位:i=0不移位,i=1向上移1行,末尾缺失用开头数据填充
        shifted = g[horse_cols].shift(-i).fillna(g[horse_cols].iloc[i]).reset_index(drop=True)
        # 重命名列名,添加后缀
        shifted.columns = [f"{col}_{suffix}" for col in horse_cols]
        # 合并到结果集
        result = pd.concat([result, shifted], axis=1)
    return result

# 执行处理并重置索引
new_df = df.groupby('raceId').apply(process_group).reset_index(drop=True)

# 输出结果(转为字典格式匹配预期)
print(new_df.to_dict('list'))

关键说明:

  • shift(-i)实现循环移位逻辑,结合fillna保证移位后末尾缺失的行用开头数据补充,形成循环效果
  • 分组处理确保不同场次的赛马数据不会互相干扰
  • 用concat直接合并列,比循环行操作的效率更高,避免原代码中merge和iterrows的性能问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:49:55