代码之家  ›  专栏  ›  技术社区  ›  Sembei Norimaki

用重复索引连接列

  •  1
  • Sembei Norimaki  · 技术社区  · 5 年前

    我有两个数据帧要水平连接,用一列的值对它们进行分组。来自 pandas.pydata website 他们这样做:

    df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']},
                       index=[0, 1, 2, 3])
    df4 = pd.DataFrame({'B': ['B2', 'B3', 'B6', 'B7'],
                        'D': ['D2', 'D3', 'D6', 'D7'],
                        'F': ['F2', 'F3', 'F6', 'F7']},
                       index=[2, 3, 6, 7])
    
    df1 = 
        A   B   C   D
    0  A0  B0  C0  D0
    1  A1  B1  C1  D1
    2  A2  B2  C2  D2
    3  A3  B3  C3  D3
    
    df4 = 
        B   D   F
    2  B2  D2  F2
    3  B3  D3  F3
    6  B6  D6  F6
    7  B7  D7  F7
    
    result = pd.concat([df1, df4], axis=1, join='inner')
    
    result = 
        A   B   C   D   B   D   F
    2  A2  B2  C2  D2  B2  D2  F2
    3  A3  B3  C3  D3  B3  D3  F3
    

    这行得通,我很高兴。 所以我使用这个技巧,通过某一列的值合并2个数据帧,基本上我用该列重新索引数据帧,然后进行连接。 但是,该列中的值是重复的,因此以具有重复索引的数据帧结尾:

    df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']},
                       index=[0, 3, 3, 2])
    df4 = pd.DataFrame({'B': ['B2', 'B3', 'B6', 'B7'],
                        'D': ['D2', 'D3', 'D6', 'D7'],
                        'F': ['F2', 'F3', 'F6', 'F7']},
                       index=[2, 3, 6, 7])
    df1 = 
        A   B   C   D
    0  A0  B0  C0  D0
    3  A1  B1  C1  D1
    3  A2  B2  C2  D2
    2  A3  B3  C3  D3
    
    df4 = 
        B   D   F
    2  B2  D2  F2
    3  B3  D3  F3
    6  B6  D6  F6
    7  B7  D7  F7
    

    因此,我希望这两个数据帧结合在一起,这样我最终将得到:

    result = 
        A   B   C   D   B   D   F
    3  A1  B1  C1  D1  B2  D2  F2
    3  A2  B2  C2  D2  B2  D2  F2
    2  A3  B3  C3  D3  B3  D3  F3
    

    (注意,在DF1中具有索引3的两行都与在DF4中具有索引3的行连接)但是这不起作用。

    ValueError: Shape of passed values is (7, 5), indices imply (7, 3)
    

    我怎样才能做到?f我可以避免按索引合并,但我可以指定一列,这样会更好。

    2 回复  |  直到 5 年前
        1
  •  2
  •   jezrael    5 年前

    一个可能的解决方案 merge 使用按索引匹配,默认 how='inner' 应该省略:

    result = pd.merge(df1, df4, left_index=True, right_index=True)
    print (result)
        A B_x   C D_x B_y D_y   F
    2  A3  B3  C3  D3  B2  D2  F2
    3  A1  B1  C1  D1  B3  D3  F3
    3  A2  B2  C2  D2  B3  D3  F3
    

    它创建重复匹配行的组合:

    df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']},
                       index=[0, 3, 3, 3])
    df4 = pd.DataFrame({'B': ['B2', 'B3', 'B6', 'B7'],
                        'D': ['D2', 'D3', 'D6', 'D7'],
                        'F': ['F2', 'F3', 'F6', 'F7']},
                       index=[2, 3, 3, 7])
    print (df1)
        A   B   C   D
    0  A0  B0  C0  D0
    3  A1  B1  C1  D1
    3  A2  B2  C2  D2
    3  A3  B3  C3  D3
    
    print (df4)
        B   D   F
    2  B2  D2  F2
    3  B3  D3  F3
    3  B6  D6  F6
    7  B7  D7  F7
    
    result = pd.merge(df1, df4, left_index=True, right_index=True)
    print (result)
        A B_x   C D_x B_y D_y   F
    3  A1  B1  C1  D1  B3  D3  F3
    3  A1  B1  C1  D1  B6  D6  F6
    3  A2  B2  C2  D2  B3  D3  F3
    3  A2  B2  C2  D2  B6  D6  F6
    3  A3  B3  C3  D3  B3  D3  F3
    3  A3  B3  C3  D3  B6  D6  F6
    
        2
  •  1
  •   Scott Boston    5 年前

    另一个可能的解决方案是 join :

    df1.join(df4,how='inner', lsuffix='_df1', rsuffix='_df4')
    

    输出:

        A B_df1   C D_df1 B_df4 D_df4   F
    2  A3    B3  C3    D3    B2    D2  F2
    3  A1    B1  C1    D1    B3    D3  F3
    3  A2    B2  C2    D2    B3    D3  F3