【问题标题】:"Anti-merge" in pandas (Python)大熊猫中的“反合并”(Python)
【发布时间】:2020-05-04 18:12:02
【问题描述】:

如何找出两个数据框中同名列之间的区别? 我的意思是我有一个名为 X 的列的数据框 A 和一个名为 X 的列的数据框 B,如果我这样做 pd.merge(A, B, on=[\'X\']),我将获得 A 和 B 的公共 X 值,但我怎样才能获得“非常见的?

    标签: python pandas merge


    【解决方案1】:

    如果您将合并类型更改为how='outer'indicator=True,这将添加一列来告诉您这些值是否仅为左/双/右:

    In [2]:
    A = pd.DataFrame({'x':np.arange(5)})
    B = pd.DataFrame({'x':np.arange(3,8)})
    print(A)
    print(B)
       x
    0  0
    1  1
    2  2
    3  3
    4  4
       x
    0  3
    1  4
    2  5
    3  6
    4  7
    
    In [3]:
    pd.merge(A,B, how='outer', indicator=True)
    
    Out[3]:
         x      _merge
    0  0.0   left_only
    1  1.0   left_only
    2  2.0   left_only
    3  3.0        both
    4  4.0        both
    5  5.0  right_only
    6  6.0  right_only
    7  7.0  right_only
    

    然后,您可以在 _merge col 上过滤生成的合并 df:

    In [4]:
    merged = pd.merge(A,B, how='outer', indicator=True)
    merged[merged['_merge'] == 'left_only']
    
    Out[4]:
         x     _merge
    0  0.0  left_only
    1  1.0  left_only
    2  2.0  left_only
    

    您还可以使用 isin 并否定掩码以查找不在 B 中的值:

    In [5]:
    A[~A['x'].isin(B['x'])]
    
    Out[5]:
       x
    0  0
    1  1
    2  2
    

    【讨论】:

      【解决方案2】:

      接受的答案在 SQL 术语中给出了所谓的LEFT JOIN IF NULL。如果您想要除匹配行之外的所有行两个都DataFrames,不只剩下。您必须向过滤器添加另一个条件,因为您要排除 both 中的所有行。

      在这种情况下,我们使用DataFrame.merge & DataFrame.query

      df1 = pd.DataFrame({'A':list('abcde')})
      df2 = pd.DataFrame({'A':list('cdefgh')})
      
      print(df1, '\n')
      print(df2)
      
         A
      0  a # <- only df1
      1  b # <- only df1
      2  c # <- both
      3  d # <- both
      4  e # <- both
      
         A 
      0  c # both
      1  d # both
      2  e # both
      3  f # <- only df2
      4  g # <- only df2
      5  h # <- only df2
      
      df = (
          df1.merge(df2, 
                    on='A', 
                    how='outer', 
                    indicator=True)
          .query('_merge != "both"')
          .drop(columns='_merge')
      )
      
      print(df)
      
         A
      0  a
      1  b
      5  f
      6  g
      7  h
      

      【讨论】:

        猜你喜欢
        • 2016-11-09
        • 2017-02-11
        • 2019-01-31
        • 2021-06-21
        • 2023-03-06
        相关资源
        最近更新 更多