【问题标题】: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() 的内容,但我不知道如何编写条件。 我希望我不会不清楚我想做什么,如果我想请告诉我。

【问题讨论】:

    标签: python python-3.x pandas list loops


    【解决方案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!是的,“复杂的算法思维”会随着时间的推移而出现竖起大拇指
    猜你喜欢
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多