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

如何在Pandas中按posteam分组并结合penalty_team条件聚合数据

问题描述

现有如下DataFrame:

import pandas as pd

df = pd.DataFrame([
        {'posteam': 'NYJ', 'defteam': 'BAL', 'penalty': 1, 'penalty_team': 'NYJ', 'penalty_yards': 10}, 
        {'posteam': 'NYJ', 'defteam': 'BAL', 'penalty': 1, 'penalty_team': 'BAL', 'penalty_yards': 5},
        {'posteam': 'BAL', 'defteam': 'NYJ', 'penalty': 0, 'penalty_team': None, 'penalty_yards': 0},
        {'posteam': 'BAL', 'defteam': 'NYJ', 'penalty': 1, 'penalty_team': 'NYJ', 'penalty_yards': 15}])

需求:按posteam中的球队统计其所有犯规次数和码数(无论该球队是进攻方还是防守方,只要penalty_team等于该球队,就计入统计),期望输出如下:

posteampenaltypenalty_yards
NYJ225
BAL15

当前使用的聚合代码仅统计了球队作为进攻方时的犯规,结果不符合预期:

df.groupby(['posteam']).agg({
    'penalty': 'sum',
    'penalty_yards': 'sum'
})

输出结果:

posteampenaltypenalty_yards
NYJ215
BAL115
解决方案

方法一:筛选有效行后按犯规球队聚合,对齐原球队列表

核心逻辑是:先过滤掉无犯规的行(penalty_team为空的行),然后按penalty_team分组统计犯规数据,最后将结果索引对齐到原posteam的所有球队,确保所有目标球队都出现在结果中。

import pandas as pd

# 过滤掉无犯规的行
filtered_df = df[df['penalty_team'].notna()]

# 按犯规球队聚合统计
result = filtered_df.groupby('penalty_team').agg(
    penalty=('penalty', 'sum'),
    penalty_yards=('penalty_yards', 'sum')
).rename_axis('posteam')  # 将索引名改为posteam,匹配期望输出

# 对齐原posteam的所有球队,填充无犯规的情况为0
result = result.reindex(df['posteam'].unique()).fillna(0).astype(int)

print(result)

运行后输出:

penalty  penalty_yards
posteam                        
NYJ            2             25
BAL            1              5

方法二:使用条件聚合(无需过滤行)

直接在聚合时加入条件判断,仅统计penalty_team与分组球队一致的行:

result = df.groupby('posteam').agg(
    penalty=('penalty', lambda x: x[df['penalty_team'] == x.name].sum()),
    penalty_yards=('penalty_yards', lambda x: x[df['penalty_team'] == x.name].sum())
)

print(result)

该方法通过lambda函数在聚合时筛选出当前分组球队(x.name即当前posteam值)作为penalty_team的行,再求和,同样能得到期望结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:35:24