使用每个独特团队获胜的顺序计数器创建列表

Posted

技术标签:

【中文标题】使用每个独特团队获胜的顺序计数器创建列表【英文标题】:Create list with sequential counter of each unique team's wins 【发布时间】:2019-06-06 14:20:36 【问题描述】:

假设我有一个数据集,其中包含 home_team、away_team 和 home_win、away_win 列,这些列告诉哪支球队赢得了比赛。像这样:

Home_team     Away_Team     Home_Win     Away_Win    gameID
   TB            CLB            1            0         1
   NY            ARZ            0            1         2
   EDM           CAN            1            0         3
   NY            TB             0            1         4
   NY            CLB            1            0         5
   TB            NY             1            0         6

您如何编写一个顺序计数器来计算球队总胜场数,而不管球队是主队还是客队。所以对于 gameID:1,每支球队总共有 0 场胜利。 由于 TB 赢得了第一场比赛,他们现在总共赢得了 1 场胜利,接下来他们将与 NY(gameID:4) 进行第二场比赛,而 NY 之前总共赢得了 0 场胜利。

因此数据将如下所示:(AT=Away_Team, HT=Home_Team)

Home_team     Away_Team     Home_Win     Away_Win    gameID    HT'sTotWins      AT'sTotWins
   TB            CLB            1            0         1            0               0
   NY            ARZ            0            1         2            0               0
   EDM           CAN            1            0         3            0               0
   NY            TB             0            1         4            0               1
   NY            CLB            1            0         5            0               0
   TB            NY             1            0         6            2               1

我已经阅读了一些关于GroupBy.cumcount() 的内容,但我不知道如何编写条件。 我希望我不会不清楚我想做什么,如果我想请告诉我。

【问题讨论】:

【参考方案1】:

为了更具指导意义,我将您的源数据扩展到 10 个游戏 和“缩短”的列名以使打印输出不那么宽。

所以脚本的第一部分,生成源DataFrame如下:

import pandas as pd

# Source data
df = pd.DataFrame(data=[
    [ 1, 'TB',  'CLB', 1], [ 2, 'NY',  'ARZ', 0],
    [ 3, 'EDM', 'CAN', 1], [ 4, 'NY',  'TB',  0],
    [ 5, 'NY',  'CLB', 1], [ 6, 'TB',  'NY',  1],
    [ 7, 'ARZ', 'CAN', 1], [ 8, 'ARZ', 'TB',  0],
    [ 9, 'NY',  'EDM', 1], [10, 'TB',  'CAN', 1]],
    columns=['gameID', 'HomeTeam', 'AwayTeam', 'HomeWin']).set_index('gameID')
df['AwayWin'] = 1 - df['HomeWin']

因为获胜队伍可以同时在HomeTeamAwayTeam,所以没有 使用单个groupby 的简单方法。 您必须使用它两次,生成每个结果列。

要生成HTWins(主队总胜数),请使用:

hWin = df.HomeTeam.where(df.HomeWin == 1, df.AwayTeam)
hCnt = hWin.groupby(hWin).cumcount()
df['HTWins'] = hCnt.where(df.HomeWin == 1, 0)

要生成ATWins(客队总胜数),请使用:

aWin = df.AwayTeam.where(df.AwayWin == 1, df.HomeTeam)
aCnt = aWin.groupby(aWin).cumcount()
df['ATWins'] = aCnt.where(df.AwayWin == 1, 0)

当你print(df)时,你会得到:

       HomeTeam AwayTeam  HomeWin  AwayWin  HTWins  ATWins
gameID                                                    
1            TB      CLB        1        0       0       0
2            NY      ARZ        0        1       0       0
3           EDM      CAN        1        0       0       0
4            NY       TB        0        1       0       1
5            NY      CLB        1        0       0       0
6            TB       NY        1        0       2       0
7           ARZ      CAN        1        0       1       0
8           ARZ       TB        0        1       0       3
9            NY      EDM        1        0       1       0
10           TB      CAN        1        0       4       0

为帮助理解此脚本的工作原理,请运行每条指令 分别打印结果。

【讨论】:

马上试试,谢谢你放下时间!!【参考方案2】:

可能有一种更“优雅”的 pandas 方法可以做到这一点,但我只会将事情分解成 for 循环并采用这种方式。

import copy
import pandas as pd

df = pd.read_csv('sports_data.csv', header=0, delim_whitespace=True)
df["HT'sTotWins"] = 0
df["AT'sTotWins"] = 0

homeWinsAwayWins = 
homeAwayCount = 'home':0, 'away':0

for index, row in df.iterrows():
    homeTeam = row['Home_team']
    awayTeam = row['Away_Team']

    if homeTeam not in homeWinsAwayWins:
        homeWinsAwayWins[homeTeam] = copy.deepcopy(homeAwayCount)
    if awayTeam not in homeWinsAwayWins:
        homeWinsAwayWins[awayTeam] = copy.deepcopy(homeAwayCount)

    df.loc[index,"HT'sTotWins"] = homeWinsAwayWins[homeTeam]['home'] + homeWinsAwayWins[homeTeam]['away']
    df.loc[index,"AT'sTotWins"] = homeWinsAwayWins[awayTeam]['home'] + homeWinsAwayWins[awayTeam]['away']

    homeWin = row['Home_Win']
    awayWin = row['Away_Win']
    if homeWin:
        homeWinsAwayWins[homeTeam]['home'] += 1
    elif awayWin:
        homeWinsAwayWins[awayTeam]['away'] += 1

print(df)

它打印你想要的。

【讨论】:

一定会尝试你优雅的解决方案,谢谢你放下时间!! 哈哈,不,MisterButter,我是说我的是优雅的版本。 @Valdi_Bo 是对 Pandas 功能的更好利用,但有时,在使用漂亮的库函数时,更难理解“幕后发生的事情”。我的方法不太简洁,但对于通用编程来说,通过它来理解它可能会有好处,特别是如果你对编程和/或 Python 比较陌生。 我对编程比较陌生,所以我已经坐了半天时间试图制定问题,这样你们就可以理解了,剩下的时间刷新页面。你写的真的在我眼里很美,即使你是“艰难的方式”,它表现出我缺乏的非常复杂的算法思维! 谢谢@MisterButter!是的,“复杂的算法思维”会随着时间的推移而出现竖起大拇指

以上是关于使用每个独特团队获胜的顺序计数器创建列表的主要内容,如果未能解决你的问题,请参考以下文章

django中列表列表的排名和计数元素

分别跟踪新记录和更新记录的计数

处理大量推文以进行探索性数据分析,例如独特推文的数量和每个用户的推文计数直方图

T-SQL计数IF函数等效项

独特的个人资料视图计数器

带计数器的独特因式分解