代码之家  ›  专栏  ›  技术社区  ›  Baron Yugovich

Pandas数据帧合并,以更多行结束

  •  -1
  • Baron Yugovich  · 技术社区  · 6 年前

    我正在做

    a_df = a_df.merge(b_df, how='left', on=['col1', col2])
    

    在这之后, a_df 实际上比操作前有更多的行。这怎么可能?

    它们都有数百万行,所以我很难缩小问题的范围。可能我遗漏了左合并的工作原理。

    1 回复  |  直到 6 年前
        1
  •  1
  •   jezrael    6 年前

    问题在于重复项,所以改为左连接 merge 返回两个副本对的所有组合 DataFrame s,检查以下样本:

    a_df = pd.DataFrame({'A':list('abcdef'),
                       'B':[4,5,4,5,5,4],
                       'C':[7,8,9,4,2,3],
                       'D':[1,3,5,7,1,0],
                       'col1':[5,5,5,9,9,9],
                       'col2':list('aaabbb')})
    
    print (a_df)
       A  B  C  D  col1 col2
    0  a  4  7  1     5    a
    1  b  5  8  3     5    a
    2  c  4  9  5     5    a
    3  d  5  4  7     9    b
    4  e  5  2  1     9    b
    5  f  4  3  0     9    b
    
    b_df = pd.DataFrame({'E':[7,8,0,1],
                         'F':list('efgh'),
                         'col1':[5,5,9,9],
                         'col2':list('aabb')})
    
    print (b_df)
       E  F  col1 col2
    0  7  e     5    a
    1  8  f     5    a
    2  0  g     9    b
    3  1  h     9    b
    

    a_df = a_df.merge(b_df, how='left', on=['col1', 'col2'])
    print (a_df)
        A  B  C  D  col1 col2  E  F
    0   a  4  7  1     5    a  7  e
    1   a  4  7  1     5    a  8  f
    2   b  5  8  3     5    a  7  e
    3   b  5  8  3     5    a  8  f
    4   c  4  9  5     5    a  7  e
    5   c  4  9  5     5    a  8  f
    6   d  5  4  7     9    b  0  g
    7   d  5  4  7     9    b  1  h
    8   e  5  2  1     9    b  0  g
    9   e  5  2  1     9    b  1  h
    10  f  4  3  0     9    b  0  g
    11  f  4  3  0     9    b  1  h
    

    解决方案1 是在第二秒内删除重复项 数据帧 :

    b_df = b_df.drop_duplicates(['col1', 'col2'])
    print (b_df)
       E  F  col1 col2
    0  7  e     5    a
    2  0  g     9    b
    
    a_df = a_df.merge(b_df, how='left', on=['col1', 'col2'])
    print (a_df)
       A  B  C  D  col1 col2  E  F
    0  a  4  7  1     5    a  7  e
    1  b  5  8  3     5    a  7  e
    2  c  4  9  5     5    a  7  e
    3  d  5  4  7     9    b  0  g
    4  e  5  2  1     9    b  0  g
    5  f  4  3  0     9    b  0  g
    

    解决方案2 是创建对的唯一值 col1 col2 按聚合:

    b_df = b_df.groupby(['col1', 'col2'], as_index=False).agg({'E':'mean', 'F': ','.join})
    print (b_df)
       col1 col2    E    F
    0     5    a  7.5  e,f
    1     9    b  0.5  g,h
    
    a_df = a_df.merge(b_df, how='left', on=['col1', 'col2'])
    print (a_df)
       A  B  C  D  col1 col2    E    F
    0  a  4  7  1     5    a  7.5  e,f
    1  b  5  8  3     5    a  7.5  e,f
    2  c  4  9  5     5    a  7.5  e,f
    3  d  5  4  7     9    b  0.5  g,h
    4  e  5  2  1     9    b  0.5  g,h
    5  f  4  3  0     9    b  0.5  g,h
    

    也可以检查所有的欺骗 df_b 通过 duplicated boolean indexing :

    print (b_df[b_df.duplicated(['col1', 'col2'], keep=False)])
    
       E  F  col1 col2
    0  7  e     5    a
    1  8  f     5    a
    2  0  g     9    b
    3  1  h     9    b