如何在Python中筛选同一Match_ID下进球后30分钟内的射门行?
筛选足球赛事中进球后30分钟内的射门记录
需求说明
从足球射门数据集中,保留同一赛事(Match_ID)里,发生在任意一次进球(Shot_Outcome为Goal)之后30分钟内的射门记录。比如示例数据中,第3行(45分钟,距30分钟进球15分钟)和第6行(47分钟,距34分钟进球13分钟)符合条件,需要保留。
实现步骤(适合Python新手)
假设你的数据集已经以pandas DataFrame形式存储,变量名为df。
方法1:直观易懂(适合小数据集)
- 提取各赛事的进球分钟数
先把每个赛事下所有进球发生的分钟数整理成字典,方便后续查询:
import pandas as pd # 筛选出所有进球记录,按Match_ID分组提取分钟数,转成字典 goal_minutes = df[df['Shot_Outcome'] == 'Goal'].groupby('Match_ID')['Minute'].apply(list).to_dict()
- 定义判断函数
写一个函数,检查单条射门记录是否满足"在某进球后30分钟内"的条件:
def check_within_30(row): # 获取当前记录的赛事ID和分钟数 match_id = row['Match_ID'] current_min = row['Minute'] # 如果该赛事没有进球,直接排除 if match_id not in goal_minutes: return False # 检查是否存在任意一个进球,满足当前时间在其之后且不超过30分钟 return any(0 <= current_min - goal_min <= 30 for goal_min in goal_minutes[match_id])
- 筛选符合条件的记录
用apply遍历每条记录,筛选出满足条件的行:
filtered_df = df[df.apply(check_within_30, axis=1)]
方法2:高效向量化操作(适合大数据集)
如果你的数据集规模很大,apply遍历会比较慢,可以用pandas的合并操作实现批量计算:
# 第一步:提取所有进球记录,并重命名分钟列 goal_records = df[df['Shot_Outcome'] == 'Goal'][['Match_ID', 'Minute']].rename(columns={'Minute': 'Goal_Minute'}) # 第二步:将原数据和进球记录按Match_ID合并,同一赛事的每个进球都会和所有射门记录配对 merged_data = df.merge(goal_records, on='Match_ID', how='left') # 第三步:筛选时间差符合条件的记录,然后去重(避免同一射门被多次匹配) filtered_df = merged_data[ (merged_data['Minute'] >= merged_data['Goal_Minute']) & (merged_data['Minute'] - merged_data['Goal_Minute'] <= 30) ].drop_duplicates(subset=df.columns)
测试验证
用你提供的示例数据测试,两种方法都会得到符合预期的结果:保留第3行和第6行的记录。
内容的提问来源于stack exchange,提问作者Oskar Mayer
相关产品推荐
相关产品推荐

