【问题标题】:How to compare all rows from a Data frame with each other and alter values, in a timely manner?如何及时比较数据框中的所有行并更改值?
【发布时间】:2022-11-19 01:36:20
【问题描述】:

我有一个包含 70,000 场比赛(行)的网球比赛的熊猫数据框,有两个问题:

  1. 每个游戏都是重复的,因为对于玩家 A 和 B 之间的每一场游戏,当 A 和 B 玩时有一行,当 B 和 A 玩时有一行。发生这种情况是因为我提取了每个玩家玩过的所有游戏,所以我有所有游戏纳达尔打过,然后是费德勒打过的所有比赛。对于我从纳达尔页面提取的比赛,纳达尔是球员 A,费德勒是球员 B,对于我从费德勒页面提取的比赛,费德勒是球员 A,纳达尔是球员 B。

  2. 第二个问题是对于每场比赛,我只有关于球员 A 的信息,所以使用前面提到的例子,对于我提取的比赛,其中纳达尔是球员 A,面对费德勒,我有纳达尔的身高、年龄和排名,但我不知道有费德勒的信息。对于我提取的比赛,其中费德勒是球员 A,面对纳达尔,我有费德勒的身高、年龄和排名,但我没有纳达尔的信息

    为了更好地理解,下面是数据示例:

    Player A Rank Height Age Tourn. Year Round Player B Result
    Nadal 3 185 37 US Open 2019 Finals Federer W
    Federer 7 183 40 US Open 2019 Finals Nadal L

    我的目标是在同一行中添加两个玩家的信息,如下所示:

    Player A Rank Height Age Tourn. Year Round Player B Rank_B Height_B Age_B Result
    Nadal 3 185 37 US Open 2019 Finals Federer 7 183 40 W

    然后删除所有重复的行。

    我已经通过在 for 循环中执行 for 循环并比较每一行来解决了这个问题。一旦满足我设定的标准,我就会继续更改线路。我认为如果在同一年、同一场比赛和同一轮比赛中,相同的球员相互对决,那么这场比赛就是重复的。

    
    import pandas as pd
    import numpy as np
    
    games = pd.read_csv("games.csv")
    
    # create the new columns to add info of opponent:
    
    games["Rank_B"] = np.nan
    games["Height_B"] = np.nan
    games["Age_B"] = np.nan
    
    
    # loop through every line:
    
    for i in range(0,len(games)):
    
        # if the row was already mark to delete skip it
    
        if games.loc[i, "p_name"] == "Delete":
            next
    
        # for each line compare it to every line:
    
        for j in range(0,len(games)):
    
            if games.loc[i, "Tourn."] == games.loc[j, "Tourn."] and games.loc[i, "Year"] == games.loc[j, "Year"] and games.loc[i, "Round"] == games.loc[j, "Round"] and games.loc[i, "Player A"] == games.loc[j, "Player B"]:
    
                games.loc[i, "Height_B"] = games.loc[j, "Height"]
                games.loc[i, "Rank_B"] = games.loc[j, "Rank"]
                games.loc[i, "Age_B"] = games.loc[j, "Age"]
    
                # marks row to delete because it is duplicate:
    
                games.loc[j, "p_name"] = "Delete"
                
                break
    
    games = games[games["p_name"].str.contains("Delete") == False]
    
    

    问题是我的解决方案非常慢,运行 70,000 行需要 12 个小时。如果我想使用 1,000,000 行的数据框运行此代码,则此解决方案不切实际。

    你能想出更好的方法来实现我的目标吗?

【问题讨论】:

  • 添加这两个原料的标准是什么?
  • 如果对于两行,tournament、year 和 round 列的值相等,并且如果玩家 a 等于玩家 b

标签: python pandas dataframe


【解决方案1】:

尝试合并:

df = pd.merge(left=df, right=df, on=['Tourn.','Round','Year'])

然后删除重复项:

df.drop_duplicates(subset=['Tourn.','Round','Year'], inplace=True)

在您只需要重命名列名之后

然后,您可以只保留具有相同玩家 A 和玩家 B 的行:

df = df[df['Player A_x'] == df['Player A_y']]

【讨论】:

  • on 参数是否可以有条件,例如 pd.merge(on=['Tourn.','Round','Year','Player A' = 'Player B']) ?
  • 查看我更新的答案
猜你喜欢
  • 2022-08-07
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-16
相关资源
最近更新 更多