Pandas DataFrame合并,最终出现更多行

时间:2018-08-03 05:09:23

标签: pandas dataframe join merge left-join

我在做

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

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

它们都具有数百万行,因此我很难缩小问题的范围。可能我缺少有关左合并如何工作的信息。

1 个答案:

答案 0 :(得分:1)

问题在于重复项,因此左联接merge返回两个DataFrame的重复项对的所有组合,请检查以下示例:

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 ​​是在第二个DataFrame中删除重复项:

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 通过聚合创建对col1col2对的唯一值:

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

还可以通过duplicatedboolean indexing检查df_b中的所有重复项:

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