【问题标题】:"Anti-merge" in pandas (Python)熊猫(Python)中的“反合并”
【发布时间】:2016-11-09 14:08:05
【问题描述】:

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

【问题讨论】:

    标签: python pandas merge


    【解决方案1】:

    接受的答案在 SQL 术语中给出了所谓的LEFT JOIN IF NULL。如果您想要除了 both 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
    

    【讨论】:

      【解决方案2】:

      如果您将合并类型更改为 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
      

      【讨论】:

        猜你喜欢
        • 2020-05-04
        • 2023-03-06
        相关资源
        最近更新 更多