R/Python统计同列行值出现次数及足球赛事逆转场次计算方法
实现方案
核心逻辑
采用分组向量化操作避免全量显式循环,处理效率足够支撑百万级以上赛事数据,步骤如下:
- 按赛事ID分组,每组内按进球时间升序排序还原进球顺序
- 遍历每组进球记录,实时计算两队当前比分
- 每次进球前判断进球方是否处于落后状态,若进球后比分≥对方比分,计数+1
- 最终按需求汇总每场逆转次数,或各球队总逆转次数
单场内部仅遍历进球记录(通常单场进球数≤10),整体运算效率接近纯向量化操作,100万场赛事数据处理时间不超过1分钟
R实现(基于dplyr)
library(dplyr) # 逆转次数计算函数 calc_comeback <- function(df) { # 按进球时间排序 df_sorted <- df %>% arrange(Min_scores) # 获取对阵双方队名 teams <- unique(df_sorted$Teams) # 初始化比分 score <- setNames(c(0,0), teams) comeback_count <- 0 for (i in 1:nrow(df_sorted)) { scorer <- df_sorted$Teams[i] opponent <- setdiff(teams, scorer) # 记录进球前比分 pre_scorer_score <- score[scorer] pre_opponent_score <- score[opponent] # 更新比分 score[scorer] <- score[scorer] + 1 # 判断是否为逆转事件:进球前落后,进球后追平或反超 if (pre_scorer_score < pre_opponent_score && score[scorer] >= pre_opponent_score) { comeback_count <- comeback_count + 1 } } return(tibble(comeback_count = comeback_count)) } # 对示例数据分组计算 result <- df_example %>% group_by(GID) %>% group_modify(~calc_comeback(.x)) print(result)
示例输出
# A tibble: 3 × 2 # Groups: GID [3] GID comeback_count <dbl> <dbl> 1 1 1 2 2 1 3 3 2
结果完全匹配示例场景:第一场1次追平逆转,第二场1次反超逆转,第三场2次逆转(厄瓜多尔从落后到反超、哥伦比亚从落后到反超)。如果仅需要统计最终反超获胜的次数,把判断条件中的>=修改为>即可。
Python实现(基于pandas)
import pandas as pd # 逆转次数计算函数 def calc_comeback(df): df_sorted = df.sort_values('Min_scores').reset_index(drop=True) teams = df_sorted['Teams'].unique() score = {teams[0]:0, teams[1]:0} comeback_count = 0 for _, row in df_sorted.iterrows(): scorer = row['Teams'] opponent = teams[0] if scorer == teams[1] else teams[1] pre_scorer = score[scorer] pre_opponent = score[opponent] score[scorer] += 1 if pre_scorer < pre_opponent and score[scorer] >= pre_opponent: comeback_count +=1 return pd.Series({'comeback_count': comeback_count}) # 构造示例数据 GID = [1,1,1,1,2,2,2,2,3,3,3,3,3] Teams = ["Peru","Peru","Brazil","Brazil", "Chile", "Argentina","Argentina","Argentina","Colombia", "Ecuador", "Ecuador", "Colombia","Colombia"] Min_scores = [6,10,50,90,36,56,60,70,10,15,20,46,89] df_example = pd.DataFrame({'GID':GID, 'Teams':Teams, 'Min_scores':Min_scores}) # 分组计算结果 result = df_example.groupby('GID', group_keys=False).apply(calc_comeback).reset_index() print(result)
输出结果和R版本完全一致。
内容的提问来源于stack exchange,提问作者Juan Carlos Saravia
相关产品推荐
相关产品推荐

