Pandas DataFrame 合并,以更多行结束

Posted

技术标签:

【中文标题】Pandas DataFrame 合并,以更多行结束【英文标题】:Pandas DataFrame merge, ends up with more rows 【发布时间】:2019-01-10 22:29:36 【问题描述】:

我在做

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

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

它们都有数百万行,所以我很难缩小问题的范围。可能我错过了有关左合并如何工作的一些信息。

【问题讨论】:

请发布记录数和预期输出较少的示例数据 数据帧有数百万行,我不可能在这里上传。 在两个df中放一个5行的样本及其预期输出 这能回答你的问题吗? Pandas Left Outer Join results in table larger than left table 【参考方案1】:

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

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

Solution1 是在第二个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

Solution2 是通过聚合创建对 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

【讨论】:

以上是关于Pandas DataFrame 合并,以更多行结束的主要内容,如果未能解决你的问题,请参考以下文章

如何扩展输出显示以查看 Pandas DataFrame 的更多列?

Pandas - 合并 DataFrame 中的行 [重复]

Python Pandas Dataframe 合并并只选择几列

Pandas:将 DataFrame 与嵌套数组结合或合并 JSON 输出

循环遍历 df 字典以合并 Pandas 中的 df

pandas基础(part4)--排序/分组/合并