【问题标题】:Aggregating after outer join using pandas使用 pandas 进行外部连接后聚合
【发布时间】:2020-12-07 12:24:19
【问题描述】:

我正在尝试将大量包含球员姓名和每年结果的 csv 文件合并到一个概览中。我每个团队都有一个 csv 文件,其中包含球员姓名、出生日期和每年的结果。在某些 csv 文件中,缺少出生日期列。尝试合并缺少生日列的文件时,我得到重复的行。

例如,对于2010年的A队,我有下面的结果表,teamA2010

    Player    Birthdate  2010
    John Doe  14-3-1999  12
    Jane Doe  15-6-1995  3

2011年同一队的成绩如下。请注意,缺少 Birthdate 列。 teamA2011

    Player    2011
    John Doe  2
    Jane Doe  1
    Alice     3

我想要的是下表:

    Player    Birthdate  2010 2011
    John Doe  14-3-1999  12   2
    Jane Doe  15-6-1995  3    1
    Alice                     3

我尝试使用外部联接合并表格(因为新玩家可能会在以后加入团队),但不确定如何汇总出生日期和年份?

    join_on = ["Player", "Birthdate"]
    if "Birthdate" in TeamA2011.columns:
       df = pd.merge(TeamA2010, TeamA2011, how='outer', on=join_on)
    else:
       join_on.remove("Birthdate")
       df = pd.merge(TeamA2010, TeamA2011, how='outer', on=join_on)
       join_on.insert(-1, "Birthdate")

结果如下表:

    Player    Birthdate  2010 2011
    John Doe  14-3-1999  12   
    John Doe                  2
    Jane Doe  15-6-1995  3    
    Jane Doe                  1
    Alice                     3

【问题讨论】:

    标签: python-3.x pandas merge


    【解决方案1】:

    当我合并有和没有生日的文件时出现了这个问题。最终,我最终合并了所有 csv 文件,并在最后汇总了结果和生日。由于生日可能会以重复或串联的 nan 值结束,因此我不得不替换这些值。

    df["Birthdate"] = pd.to_datetime(df["Birthdate"])
    df["Birthdate"] = df["Birthdate"].dt.strftime('%d %B %Y').astype(str)
    group_by.remove("Birthdate")
    df = df.groupby(group_by, as_index=False).agg(' '.join)
    
    df["Birthdate"] = df["Birthdate"].str.replace(" nan", "")
    df["Birthdate"] = df["Birthdate"].str.replace("nan ", "")
    df["Birthdate"].loc[df["Birthdate"].str.count(" ") > 2] = df["Birthdate"].str[0:((df["Birthdate"].str.len()+1)/2).round()]
    

    【讨论】:

      【解决方案2】:

      右外连接:

      df = pd.merge(teamA2010, teamA2011, how="right", on="Player")
      

      输出:

           Player   Birthday 2010 2011
      0  John Doe  14-3-1999   12    2
      1  Jane Doe  15-6-1995    3    1
      2     Alice        NaN  NaN    3
      

      【讨论】:

        【解决方案3】:

        假设你想实现这个

          Player    Birthdate  2010 2011
            John Doe  14-3-1999  12   2
            Jane Doe  15-6-1995  3    1
            Alice                     3
        

        我会这样做:

        df3 = pd.merge(df1, df2, how="outer", on="Player")
        其中
        df1 is the first df you provideddf2 is the 2nd one

        编辑
        您无需加入 Bitrtday,即使有多个同名和不同生日日期的玩家。外部联接将处理此问题。 整个代码:

        df1 = pd.DataFrame([["John Doe","14-3-1999","12"],
                        ["John Doe", "1-1-1999"],
                        ["Jane Doe","15-6-1995","3"]], columns=["Player","Birthday","2010"])
        
        df2 = pd.DataFrame([["John Doe", "2"],["Jane Doe", "1"], ["Alice", "3"]], columns=["Player","2011"])
        
        
        df3 = pd.merge(df1, df2, how="outer", on="Player")
        print(df3)
        
        Out:
             Player   Birthday  2010 2011
        0  John Doe  14-3-1999    12    2
        1  John Doe   1-1-1999  None    2
        2  Jane Doe  15-6-1995     3    1
        3     Alice        NaN   NaN    3
        

        【讨论】:

          猜你喜欢
          • 2018-03-15
          • 1970-01-01
          • 2019-10-12
          • 2020-06-29
          • 2012-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-21
          相关资源
          最近更新 更多