【问题标题】:Merge: discard duplicates that do not exist in both left and right dataframes?合并:丢弃左右数据帧中不存在的重复项?
【发布时间】:2021-12-12 01:17:33
【问题描述】:

我有来自两个来源的相同数据。两者都在熊猫DataFrames 中。正在发生一些事情:

  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 

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

问题:

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

【问题讨论】:

    标签: python pandas dataframe join merge


    【解决方案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
    

    【讨论】:

    • 它有效。只需花一点时间了解每个链接操作,以防我需要澄清。
    • 好的,聪明但简单。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2015-12-19
    • 2016-03-15
    • 2022-01-08
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    相关资源
    最近更新 更多