合并:丢弃左右数据框中都不存在的重复项?

Merge: discard duplicates that do not exist in both left and right dataframes?

我有来自两个来源的相同数据。两者都在 pandas DataFrame 秒。一些事情正在发生:

  1. 由于某些旧软件的读取错误,来自source 1(左)的数据只是来自source 2(右)的数据的一个子集。
  2. 来自 source 2 的数据多了一列。
  3. 两个数据源都可能包含有效的重复值。
  4. 两者之间没有共享唯一键。

期望的结果

  1. 我想合并两者,保持交集。
  2. 仅当两个数据框中都存在重复项时才应保留重复项。这似乎很难,因为两个数据帧的长度不同并且没有共享唯一键。
  3. 第二个数据框中的额外列应该在新的合并数据框中。

工作示例/我尝试过的

这是一个简单的例子:

df1 = pd.DataFrame( 
    { # last entry a duplicate of the first
        'var1' : [1, 2, 3, 1,], 
        'var2'  : ['a', 'b', 'c', 'a']
    }
)

df2 = pd.DataFrame(  
    { # last two entries duplicates of first two.
    'cat': [1, 2, 3, 4, 1, 2],
    'var1' : [1, 2, 3, 4, 1, 2],
    'var2'  : ['a', 'b', 'c', 'd', 'a', 'b']
    }
)


merged = pd.merge(df1, df2, on=["var1", "var2"], how="inner")
merged

结果:

# - indicates undesired duplicates
  var1 var2 cat
0   1   a   1 
1   1   a   1 
2   1   a   1 #
3   1   a   1 #
4   2   b   2 
5   2   b   2 #
6   3   c   3 

但我期待的是(顺序无关紧要):

  var1 var2 cat
0   1   a   1 
1   1   a   1 
2   2   b   2 
3   3   c   3 

我查看了删除重复项,但它不会歧视并破坏有价值的信息。


merged.drop_duplicates()

  var1 var2 cat
0   1   a   1
4   2   b   2
6   3   c   3

我的一个想法是想出一种方法,让两个以上的二进制列在合并之前标识源,并删除两个列都不正确的任何行。

  var1 var2 cat src1 src2
0   1   a   1    1     1 
1   1   a   1    1     1
2   1   a   1    0     1 # drop
3   1   a   1    0     1 # drop
4   2   b   2    1     1
5   2   b   2    0     1 # drop
6   3   c   3    1     1 

但是,我不确定如何在合并期间实现这种标记(如果可能的话)。

问题:

所以,简而言之,问题是 “如何合并两个表,仅当它们存在于两个表中时才允许保留重复项”?

尝试与枚举合并:

key_cols = ['var1','var2']
(df1.assign(enum=df1.groupby(key_cols).cumcount())
    .merge(df2.assign(enum=df2.groupby(key_cols).cumcount()),
           on=['enum'] + key_cols, how='inner')
    .drop('enum', axis=1)
)

输出:

   var1 var2  cat
0     1    a    1
1     2    b    2
2     3    c    3
3     1    a    1