"反合并"在熊猫(Python)

时间:2016-07-07 09:48:06

标签: python pandas merge

如何在两个数据框中找出同名列之间的差异? 我的意思是我有一个名为X的列的数据框A和名为X的列的数据框B,如果我pd.merge(A, B, on=['X']),我将获得A和B的常见X值,但我怎样才能得到& #34;非共同"的?

2 个答案:

答案 0 :(得分:26)

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

答案 1 :(得分:3)

可接受的答案用SQL术语给出了一个LEFT JOIN IF NULL。如果要除两者 DataFrames中的匹配行之外的所有行,不仅要保留。您必须向过滤器添加其他条件,因为您要排除both中的所有行。

在这种情况下,我们使用DataFrame.mergeDataFrame.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