比较多个列以获取两个Pandas Dataframe中不同的行

时间:2015-11-04 14:10:01

标签: python pandas

我有两个数据帧:

df1=
    A    B   C
0   A0   B0  C0
1   A1   B1  C1
2   A2   B2  C2

df2=
    A    B   C
0   A2   B2  C10
1   A1   B3  C11
2   A9   B4  C12

我希望在df1中找到基于一列或两列(或更多列)在df2中找不到的行。因此,如果我只比较列'A',则在df2中找不到df1中的以下行(请注意,列'B'和列'C'不用于df1和df2之间的比较)

    A    B   C
0   A0   B0  C0

我想用

返回一个系列
0   False
1   True
2   True

或者,如果我只比较列'A'和列'B',则在df2中找不到df1中的以下行(请注意,列'C'不用于df1和df2之间的比较)

    A    B   C
0   A0   B0  C0
1   A1   B1  C1

我想要用

返回一个系列
0   False
1   False
2   True

我知道如何使用套装完成此操作,但我正在寻找一种简单的Pandas方法来实现这一目标。

4 个答案:

答案 0 :(得分:3)

理想情况下,人们希望能够使用~df1 [COLS] .isin(df2 [COLS])作为掩码,但这需要索引标签匹配(https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.isin.html

这是一个使用.isin的简洁表单,但将第二个DataFrame转换为dict,以便索引标签不需要匹配:

COLS = ['A', 'B'] # or whichever columns to use for comparison

df1[~df1[COLS].isin(df2[COLS].to_dict(
    orient='list')).all(axis=1)]

答案 1 :(得分:2)

 ~df1['A'].isin(df2['A'])

应该为你提供你想要的系列

df1[ ~df1['A'].isin(df2['A'])]

数据框:

    A   B   C
0   A0  B0  C0

答案 2 :(得分:2)

如果您的版本为0.17.0,那么您可以使用pd.merge并传递感兴趣的cols,how ='left'并将indicator=True设置为值是仅存在于左侧还是都。然后,您可以测试附加的_merge col是否等于'both':

In [102]:
pd.merge(df1, df2, on='A',how='left', indicator=True)['_merge'] == 'both'

Out[102]:
0    False
1     True
2     True
Name: _merge, dtype: bool

In [103]:
pd.merge(df1, df2, on=['A', 'B'],how='left', indicator=True)['_merge'] == 'both'

Out[103]:
0    False
1    False
2     True
Name: _merge, dtype: bool

合并输出:

In [104]:
pd.merge(df1, df2, on='A',how='left', indicator=True)

Out[104]:
    A B_x C_x  B_y  C_y     _merge
0  A0  B0  C0  NaN  NaN  left_only
1  A1  B1  C1   B3  C11       both
2  A2  B2  C2   B2  C10       both

In [105]:    
pd.merge(df1, df2, on=['A', 'B'],how='left', indicator=True)

Out[105]:
    A   B C_x  C_y     _merge
0  A0  B0  C0  NaN  left_only
1  A1  B1  C1  NaN  left_only
2  A2  B2  C2  C10       both

答案 3 :(得分:1)

方法(1)

In [63]:
df1['A'].isin(df2['A']) & df1['B'].isin(df2['B'])
Out[63]:

0   False
1   False
2   True

方法(2)

您可以使用左侧合并来获取仅存在于第一个数据框中的两个帧+值中存在的值

In [10]:
left = pd.merge(df1 , df2 , on = ['A' , 'B'] ,how = 'left')
left
Out[10]:
    A   B   C_x C_y
0   A0  B0  C0  NaN
1   A1  B1  C1  NaN
2   A2  B2  C2  C10

当然,仅存在于第一帧中的值将在另一个数据框的列中具有NAN值,然后您可以通过执行以下操作来过滤此NAN

In [16]:
left.loc[pd.isnull(left['C_y']) , 'A':'C_x']
Out[16]:
    A   B   C_x
0   A0  B0  C0
1   A1  B1  C1

In [17]:

如果您想了解AB中的值是否存在,您可以执行以下操作

In [20]:
pd.notnull(left['C_y'])
Out[20]:
0    False
1    False
2     True
Name: C_y, dtype: bool