使用Pandas groupby处理篮球赛事数据,生成背靠背状态标识列
使用Pandas GroupBy处理篮球赛事背靠背赛程标记
核心思路
要实现需求,需先跟踪每支队伍的参赛时间线,通过分组梳理每支队伍的历史赛程,再判断当前比赛的主/客场队伍是否处于背靠背赛程末尾,最后将结果关联回原数据。
代码实现
1. 导入依赖并预处理数据
先将日期转换为可计算的datetime格式,方便后续日期差判断:
import pandas as pd # 加载输入数据(补充期望输出中的9/21记录以覆盖完整场景) data = { 'date': ['9/21/22', '9/22/22', '9/23/22'], 'home_team': ['LAL', 'LAL', 'LAC'], 'away_team': ['MIN', 'DET', 'LAL'] } df = pd.DataFrame(data) # 转换日期格式为datetime,支持日期运算 df['date'] = pd.to_datetime(df['date'])
2. 构建队伍参赛日志
把主客场记录统一拆分为「队伍-参赛日期-对手」结构,按队伍分组后获取前一次参赛信息:
# 拆分主客场记录,生成每支队伍的参赛日志 home_entries = df[['date', 'home_team', 'away_team']].rename(columns={'home_team': 'team', 'away_team': 'opponent'}) away_entries = df[['date', 'away_team', 'home_team']].rename(columns={'away_team': 'team', 'home_team': 'opponent'}) team_schedule = pd.concat([home_entries, away_entries]).sort_values(['team', 'date']) # 按队伍分组,获取上一次参赛的日期和对手 team_schedule['prev_match_date'] = team_schedule.groupby('team')['date'].shift(1) team_schedule['prev_opponent'] = team_schedule.groupby('team')['opponent'].shift(1) # 判断是否为背靠背(上一次参赛日期为前一天) team_schedule['is_back_to_back'] = team_schedule['date'] - team_schedule['prev_match_date'] == pd.Timedelta(days=1)
3. 关联回原数据生成目标列
将队伍的背靠背信息匹配到原数据的主客场字段,生成要求的列:
# 为主场队伍匹配背靠背信息 df = df.merge( team_schedule[['team', 'date', 'prev_opponent', 'is_back_to_back']], left_on=['home_team', 'date'], right_on=['team', 'date'], how='left' ).rename(columns={'prev_opponent': 'yesterday_home_team', 'is_back_to_back': 'home_back_to_back'}) # 为客场队伍匹配背靠背信息 df = df.merge( team_schedule[['team', 'date', 'prev_opponent', 'is_back_to_back']], left_on=['away_team', 'date'], right_on=['team', 'date'], how='left', suffixes=('', '_away') ).rename(columns={'prev_opponent': 'yesterday_away_team', 'is_back_to_back_away': 'away_back_to_back'}) # 按规则填充0值:非背靠背则设为0,否则保留对手 df['yesterday_home_team'] = df.apply(lambda x: x['yesterday_home_team'] if x['home_back_to_back'] else 0, axis=1) df['yesterday_away_team'] = df.apply(lambda x: x['yesterday_away_team'] if x['away_back_to_back'] else 0, axis=1) # 清理冗余列并整理格式 df = df.drop(['team', 'team_away', 'home_back_to_back', 'away_back_to_back'], axis=1) df = df.sort_values('date').reset_index(drop=True) df['date'] = df['date'].dt.strftime('%m/%d/%y')
4. 最终输出
运行代码后得到结果:
date home_team away_team yesterday_home_team yesterday_away_team 0 09/21/22 LAL MIN 0 MIN 1 09/22/22 LAL DET DET 0 2 09/23/22 LAC LAL LAL LAC
关键逻辑说明
- 统一参赛日志:将每场比赛拆为主队、客队两条记录,确保能完整跟踪每支队伍的所有赛程。
- GroupBy移位:通过
shift(1)获取每支队伍上一次参赛的日期,判断是否与当前日期间隔1天,以此确认背靠背状态。 - 关联匹配:将队伍的背靠背信息精准匹配回原数据的主客场字段,生成符合要求的标记列。
内容的提问来源于stack exchange,提问作者Brad
相关产品推荐
相关产品推荐

