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

如何不使用for循环在Pandas中填充网球对战的last_winner字段?

用apply替代for loop填充网球对战历史胜者

需求说明

给定网球比赛数据集,需为每条记录填充对战双方此前的最后一位胜者,无历史对战则填"none"。

原始数据

player_1player_2winnerlast_winner
FedererNadalFederer
DjokoFedererDjoko
NadalFedererNadal
DjokoFedererFederer
MurrayDjokoMurray
DjokoFedererDjoko

目标输出

player_1player_2winnerlast_winner
FedererNadalFederernone
DjokoFedererDjokonone
NadalFedererNadalFederer
DjokoFedererFedererDjoko
MurrayDjokoMurraynone
DjokoFedererDjokoFederer

现有for loop实现

for i,j in tennis.iterrows() :
    
    try :
        tennis.loc[i, 'last_winner'] = tennis.iloc[:i].loc[(tennis.player_1.isin([j.player_1, j.player_2]) & tennis.player_2.isin([j.player_1, j.player_2])), "winner"].iloc[-1]
    except:
        tennis.loc[i, 'last_winner'] = "none"

用apply实现的替代方案

当然可以用apply结合自定义函数实现,核心是先为每对对战组合生成唯一标识(忽略球员顺序),再针对每行回溯历史记录:

步骤1:生成对战组合唯一键

为了统一A vs B和B vs A的对战标识,将两位球员按字母排序后拼接:

def create_match_key(row):
    return '-'.join(sorted([row['player_1'], row['player_2']]))

tennis['match_key'] = tennis.apply(create_match_key, axis=1)

步骤2:自定义函数获取历史最后胜者

遍历每行,筛选当前行之前的同组合记录,取最后一个胜者:

def get_previous_winner(row):
    # 取当前行之前的所有记录,筛选同对战组合的条目
    prior_matches = tennis.loc[:row.name - 1][tennis['match_key'] == row['match_key']]
    return prior_matches['winner'].iloc[-1] if not prior_matches.empty else 'none'

# 应用函数填充last_winner列
tennis['last_winner'] = tennis.apply(get_previous_winner, axis=1)

# 可选:删除临时生成的match_key列
tennis = tennis.drop(columns=['match_key'])

方案优势

  • 代码结构更清晰,逻辑拆分明确;
  • 相比iterrows()的逐行循环,apply更贴合pandas的API设计,可读性更强;
  • 对战组合的唯一键避免了重复判断player_1和player_2的双向匹配,减少逻辑冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:20:47