代码之家  ›  专栏  ›  技术社区  ›  ojunk

`pandas.merge`无法识别相同的索引

  •  2
  • ojunk  · 技术社区  · 7 年前

    我有两个列重叠但索引相同的数据帧,我想将它们组合起来。我觉得这应该是直截了当的,但我已经通过了太多的例子和问题,它不起作用,但似乎与其他例子不一致。

    import pandas as pd
    # create test data
    df = pd.DataFrame({'gen1': [1, 0, 0, 1, 1], 'gen3': [1, 0, 0, 1, 0], 'gen4': [0, 1, 1, 0, 1]}, index = ['a', 'b', 'c', 'd', 'e'])
    df1 = pd.DataFrame({'gen1': [1, 0, 0, 1, 1], 'gen2': [0, 1, 1, 1, 1], 'gen3': [1, 0, 0, 1, 0]}, index = ['a', 'b', 'c', 'd', 'e'])
    
    In [1]: df
    Out[1]: 
       gen1  gen2  gen3
    a     1     0     1
    b     0     1     0
    c     0     1     0
    d     1     1     1
    e     1     1     0
    
    In [2]: df1
    Out[2]: 
       gen1  gen3  gen4
    a     1     1     0
    b     0     0     1
    c     0     0     1
    d     1     1     0
    e     1     0     1
    

    https://pandas.pydata.org/pandas-docs/stable/merging.html )我确信我找到了正确的例子(合并的第一个和第二个例子)。第二个例子是:

    In [43]: result = pd.merge(left, right, on=['key1', 'key2'])
    

    在他们的示例中,他们有两个DFs(左和右),它们具有重叠的列和相同的索引,并且它们生成的数据帧具有每个列和原始索引的一个版本,但我这样做时不会发生这种情况:

    # get the intersection of columns (I need this to be general)
    In [3]: column_intersection = list(set(df).intersection(set(df1))
    
    In [4]: pd.merge(df, df1, on=column_intersection)
    Out[4]: 
       gen1  gen2  gen3  gen4
    0     1     0     1     0
    1     1     0     1     0
    2     1     1     1     0
    3     1     1     1     0
    4     0     1     0     1
    5     0     1     0     1
    6     0     1     0     1
    7     0     1     0     1
    8     1     1     0     1
    

    这里我们看到merge没有看到索引是相同的!我在选项上做了手脚,但没有得到我想要的结果。

    How to keep index when using pandas merge 但我并不真正理解答案,因此无法将其与我的问题联系起来。

    此特定示例的要点:

    • 索引将始终相同。

    对于这个特定的问题有一个解决方案是很好的,但我也很想理解它,因为我发现自己经常花很多时间来组合数据帧。我喜欢熊猫,总的来说,我觉得它非常直观,但除了数据帧的琐碎组合之外,我似乎对其他任何东西都感到不舒服。

    2 回复  |  直到 6 年前
        1
  •  3
  •   cs95 abhishek58g    7 年前

    从v0.23开始,可以为连接键指定索引名(如果有的话)。

    df.index.name = df1.index.name = 'idx'
    df.merge(df1, on=list(set(df).intersection(set(df1)) | {'idx'}))
    
         gen1  gen3  gen4  gen2
    idx                        
    a       1     1     0     0
    b       0     0     1     1
    c       0     0     1     1
    d       1     1     0     1
    e       1     0     1     1 
    

    pd.concat

    c = list(set(df).intersection(set(df1)))
    pd.concat([df1, df.drop(c, 1)], axis=1)
    
         gen1  gen2  gen3  gen4                     
    a       1     0     1     0
    b       0     1     0     1
    c       0     1     0     1
    d       1     1     1     0
    e       1     1     0     1
    
        2
  •  2
  •   piRSquared    7 年前

    在这种特殊情况下,您可以使用 assign
    事情 df df1 包括在内。

    df1.assign(**df)
    
       gen1  gen2  gen3  gen4
    a     1     0     1     0
    b     0     1     0     1
    c     0     1     0     1
    d     1     1     1     0
    e     1     1     0     1
    

    **df 打开 df 分配 以列的名称作为关键字,以列作为参数。

    这和

    df1.assign(gen1=df.gen1, gen3=df.gen3, gen4=df.gen4)