【问题标题】:How to sum values of one column based on other columns in pandas?如何根据熊猫中的其他列对一列的值求和?
【发布时间】:2020-11-12 15:26:20
【问题描述】:

使用如下所示的数据框(文本版本如下):

我应该计算自 2010 年以来哪个国家/地区在锦标赛中的进球最多。到目前为止,我已经设法通过过滤掉这样的友谊来操纵数据框:

no_friendlies = df[df.tournament != "Friendly"]

然后我将日期列设置为索引,以便过滤掉 2010 年之前的所有匹配项:

no_friendlies_indexed = no_friendlies.set_index('date')
since_2010 = no_friendlies_indexed.loc['2010-01-01':]

从这一点开始,我很迷茫,因为我不知道如何计算每个国家/地区的主客场进球数

感谢任何帮助/建议!

编辑:

示例数据的文本版本:

date    home_team   away_team   home_score  away_score  tournament  city    country     neutral
0   1872-11-30  Scotland    England     0   0       Friendly    Glasgow     Scotland    False
1   1873-03-08  England     Scotland    4   2       Friendly    London  England     False
2   1874-03-07  Scotland    England     2   1       Friendly    Glasgow     Scotland    False
3   1875-03-06  England     Scotland    2   2       Friendly    London  England     False
4   1876-03-04  Scotland    England     3   0       Friendly    Glasgow     Scotland    False
5   1876-03-25  Scotland    Wales       4   0       Friendly    Glasgow     Scotland    False
6   1877-03-03  England     Scotland    1   3       Friendly    London  England     False
7   1877-03-05  Wales       Scotland    0   2       Friendly    Wrexham     Wales   False
8   1878-03-02  Scotland    England     7   2       Friendly    Glasgow     Scotland    False
9   1878-03-23  Scotland    Wales       9   0       Friendly    Glasgow     Scotland    False
10  1879-01-18  England     Wales       2   1       Friendly    London  England     False

编辑 2:

我刚刚尝试过这样做:

since_2010.groupby(['home_team', 'home_score']).sum()

但它不会返回主队得分的总和(如果这有效,我会重复它为客队得到总分)

【问题讨论】:

  • 粘贴示例数据的文本版本
  • 和预期输出
  • 您需要重新调整它,以便有 3(或 4)列类似于 ['date', 'team', 'Home_or_Away', 'score']。 pd.wide_to_long 或 melt 可以做到这一点。
  • @ALollz 说了什么,然后是 .groupby Team_name 并得到 Score 的 sum()。
  • 我刚刚粘贴了文本版本的数据

标签: python pandas kaggle


【解决方案1】:

.groupby 和 .sum() 用于主队,然后对客队执行相同操作并将两者相加:

df_new = df.groupby('home_team')['home_score'].sum() + df.groupby('away_team')['away_score'].sum()

输出:

England     12
Scotland    34
Wales        1

更详细的解释(每条评论):

  1. 您只需要.groupby 一列home_team。在您的回答中,您按['home_team', 'home_score'] 分组您的目标(不是双关语)是获得home_score 的.sum() - 所以您应该不 .groupby() 它。如您所见,['home_score'] 在我使用.groupby 的部分之后,因此我可以得到它的.sum()。这让您为主队做好准备。
  2. 然后,您对away_team 执行相同的操作。
  3. 此时 python / pandas 已经足够聪明了,因为 home_team 和 away_team 组的结果对于国家/地区具有相同的值,您可以简单地将它们加在一起...

【讨论】:

  • 您好,非常感谢您的帮助。这似乎奏效了。如果您有时间,您能否解释一下您的代码和我的代码之间的区别,因为我在发布之前也尝试使用 groupby 但它不起作用:df.groupby(['home_team', 'home_score' ]).sum()
  • @sak 您只需按一列分组home_team。在您的回答中,您按['home_team', 'home_score'] 分组您的目标(没有双关语)是获得home_score 的sum() - 所以您不应该按它分组。如您所见,['home_score'] 在我使用.groupby 的部分之后,因此我可以得到它的.sum()。这让您为home 团队做好准备。然后,您对 away 团队执行相同的操作。此时 python / pandas 足够聪明,因为home 和away 组的结果对于国家/地区具有相同的值,您可以简单地将它们加在一起......
  • 智能简单:D。尽管一支球队不太可能只作为主队或客队参加一场比赛,但您可以考虑使用Series.add 和fill_value=0(df.groupby('home_team')['home_score'].sum().add(df.groupby('away_team')['away_score'].sum(), fill_value=0)) 正常情况下+ 加法将导致球队缺席一场比赛的总和)系列为NaN,不分其他得分:
  • 这是一个很好的观点,尽管我同意一支球队永远离开/回家的可能性很小。正如您在所有或大多数运动中可能知道的那样,球队的时间表是 50% 主场和 50% 客场:)。不过,对于我同意的其他类型的数据,您可能需要更稳健的方法。
  • 再次感谢您的解释!这个讨论也帮助我理解使用这种类型的数据
【解决方案2】:

使用pd.wide_to_long 重塑。好处是它会自动创建一个'home_or_away' 指标,但我们将首先将列更改为“score_home”(而不是“home_score”)。

# Swap column stubs around `'_'`
df.columns = ['_'.join(x[::-1]) for x in df.columns.str.split('_')]

# Your code to filter, would drop everything in your provided example
# df['date'] = pd.to_datetime(df['date'])
# df[df['date'].dt.year.gt(2010) & df['tournament'].ne('Friendly')]

df = pd.wide_to_long(df, i='date', j='home_or_away',
                     stubnames=['team', 'score'], sep='_', suffix='.*')

#                          country  neutral tournament     city      team  score
#date       home_or_away                                                        
#1872-11-30 home          Scotland    False   Friendly  Glasgow  Scotland      0
#1873-03-08 home           England    False   Friendly   London   England      4
#1874-03-07 home          Scotland    False   Friendly  Glasgow  Scotland      2
#...
#1878-03-02 away          Scotland    False   Friendly  Glasgow   England      2
#1878-03-23 away          Scotland    False   Friendly  Glasgow     Wales      0
#1879-01-18 away           England    False   Friendly   London     Wales      1

所以现在无论主场还是客场,都可以获得积分:

df.groupby('team')['score'].sum()
#team
#England     12
#Scotland    34
#Wales        1
#Name: score, dtype: int64

【讨论】:

  • 这个太好了,以前没用过wide to long功能,非常感谢您的详细回复!
猜你喜欢
  • 2019-09-09
  • 2020-07-12
  • 1970-01-01
  • 2020-04-13
  • 2018-05-08
  • 2022-11-02
  • 2013-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多