如何用Pandas/PySpark计算同时参与主客场的球队总比赛数?
Pandas 更优实现方案
不用分开统计主客场再关联,直接将两列合并后统一统计,再筛选同时存在的球队,代码更简洁高效:
import pandas as pd # 假设你的数据集存储在df中 # 1. 将HomeTeam和AwayTeam列转置为单列,保留球队名称 melted = df.melt(value_vars=['HomeTeam', 'AwayTeam'], value_name='Team') # 2. 统计每个球队的总参赛场次 total_matches = melted.groupby('Team').size().reset_index(name='TotalMatches') # 3. 筛选同时出现在主客场的球队 common_teams = set(df['HomeTeam'].unique()) & set(df['AwayTeam'].unique()) final_result = total_matches[total_matches['Team'].isin(common_teams)]
PySpark 更优实现方案
方法1:使用stack函数(Spark 3.1+)
通过stack快速合并主客场列,一次分组完成统计:
from pyspark.sql.functions import col, count # 假设你的Spark DataFrame名为df # 1. 合并主客场球队列 stacked_df = df.selectExpr("stack(2, 'Home', HomeTeam, 'Away', AwayTeam) as (Type, Team)") # 2. 统计总场次 team_totals = stacked_df.groupBy('Team').agg(count('*').alias('TotalMatches')) # 3. 获取同时存在于主客场的球队集合 home_teams = set(df.select('HomeTeam').distinct().rdd.flatMap(lambda x: x).collect()) away_teams = set(df.select('AwayTeam').distinct().rdd.flatMap(lambda x: x).collect()) common_teams = list(home_teams & away_teams) # 4. 筛选结果 final_result = team_totals.filter(col('Team').isin(common_teams)) final_result.show()
方法2:使用union(兼容低版本Spark)
如果你的Spark版本低于3.1,用union合并主客场数据:
from pyspark.sql.functions import col, count # 拆分主客场数据并合并 home_teams_df = df.select(col('HomeTeam').alias('Team')) away_teams_df = df.select(col('AwayTeam').alias('Team')) combined_df = home_teams_df.union(away_teams_df) # 统计总场次 team_totals = combined_df.groupBy('Team').agg(count('*').alias('TotalMatches')) # 筛选同时存在的球队(步骤同方法1) final_result = team_totals.filter(col('Team').isin(common_teams))
这些方法只需要一次分组统计,避免了两次分组后的关联操作,减少了代码复杂度,同时提升了计算效率。
内容的提问来源于stack exchange,提问作者reddevil
相关产品推荐
相关产品推荐

