合并具有重复值的数据框上的项目

时间:2018-03-19 13:57:10

标签: python pandas dataframe merge duplicates

所以我有一个数据框(或系列),其中每个列' A'总共出现4次,如下所示:

df = pd.DataFrame([['foo'],
                   ['foo'],
                   ['foo'],
                   ['foo'],
                   ['bar'],
                   ['bar'],
                   ['bar'],
                   ['bar']],
                  columns=['A'])
       A
0    foo
1    foo
2    foo
3    foo
4    bar
5    bar
6    bar
7    bar

我还有另一个数据框,其值类似于A列中的值,但它们并不总是有4个值。它们还有更多列,如下所示:

df_key = pd.DataFrame([['foo', 1, 2],
                       ['foo', 3, 4],
                       ['bar', 5, 9],
                       ['bar', 2, 4],
                       ['bar', 1, 9]],
                      columns=['A', 'B', 'C'])

       A    B    C
0    foo    1    2
1    foo    3    4
2    bar    5    9
3    bar    2    4
4    bar    1    9

我想合并他们,他们最终使用类似的东西:

df.merge(df_key, how='left', on='A', copy=False)

       A    B    C
0    foo    1    2
1    foo    3    4
2    foo  NaN  NaN
3    foo  NaN  NaN
4    bar    5    9
5    bar    2    4
6    bar    1    9
7    bar  NaN  NaN

但我最终得到了类似的东西。有什么建议吗?

      A    B        C
 0  foo    1        2
 1  foo    3        4
 2  foo    1        2
 3  foo    3        4
 4  foo    1        2
 5  foo    3        4
 6  foo    1        2
 7  foo    3        4
 8  bar    5        9
 9  bar    2        4
 10 bar    1        9
 11 bar    5        9
 12 bar    2        4
 13 bar    1        9
 14 bar    5        9
 15 bar    2        4
 16 bar    1        9
 17 bar    5        9
 18 bar    2        4
 19 bar    1        9

2 个答案:

答案 0 :(得分:7)

您需要使用groupby + cumcountmerge来创建代理列。

i = df.assign(D=df.groupby('A').cumcount())
j = df_key.assign(D=df_key.groupby('A').cumcount())

i.merge(j, on=['A', 'D'], how='left').drop('D', 1)

     A    B    C
0  foo  1.0  2.0
1  foo  3.0  4.0
2  foo  NaN  NaN
3  foo  NaN  NaN
4  bar  5.0  9.0
5  bar  2.0  4.0
6  bar  1.0  9.0
7  bar  NaN  NaN

答案 1 :(得分:3)

或者您可以从df_key重复df剩余次数的A列。

s=df.A.value_counts()-df_key.A.value_counts()

pd.concat([df_key,pd.DataFrame({'A':s.index.repeat(s)})]).sort_values('A')
Out[469]: 
     A    B    C
2  bar  5.0  9.0
3  bar  2.0  4.0
4  bar  1.0  9.0
0  bar  NaN  NaN
0  foo  1.0  2.0
1  foo  3.0  4.0
1  foo  NaN  NaN
2  foo  NaN  NaN