2016-11-23 60 views
1

我有一个数据帧df1与多列。我有同一组列的df2。我想获得df1中不存在的df1记录。我能执行此任务如下:基于熊猫中的一对列进行匹配

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

现在我想同样的操作,但在名称和ID的组合。这意味着,如果来自df1的作为一对的名称和ID在df2中同时存在,那么整个记录不应该是我结果的一部分。

如何使用熊猫来完成此任务?

+0

通过串联'NAME'创建一个新的列和'ID'并使用这个新的列,就像你在问题中使用'ID'一样。 – burhan

回答

0

这其实很容易。

df1[(~df1[['ID', 'Name']].isin(df2[['ID', 'Name']])).any(axis=1)] 

您将要比较的列名作为列表传递。有趣的部分是它输出的内容。

比方说df1等于:

ID Name 
0 0  0 
1 1  1 
2 2  2 
3 3  3 
4 4  4 
5 5  5 
6 6  6 
7 7  7 
8 8  8 
9 1  1 

而且df2等于:

ID Name 
0 0  0 
1 1  1 
2 2  2 
3 3  3 
4 4  4 
5 5  5 
6 6  6 
7 7  7 
8 8  8 
9 1  9 

df1df2比赛之间的每一个(ID, Name)对除为行9.我的回答的结果将返回:

ID Name 
9 1  1 

这正是你想要的。

详细地说,当你做面膜:

~df[['ID', 'Name']].isin(df2[['ID', 'Name']] 

你得到这样的:

 ID Name 
0 False False 
1 False False 
2 False False 
3 False False 
4 False False 
5 False False 
6 False False 
7 False False 
8 False False 
9 False True 

我们要选择的排在那里的一列是真实的。对于这一点,我们可以添加any(axis=1)其上创建结束:

0 False 
1 False 
2 False 
3 False 
4 False 
5 False 
6 False 
7 False 
8 False 
9  True 

然后当你使用索引这个系列,它只会选择行9

0

您可以通过连接NAME和ID创建新列,并使用这个新列在你的问题中使用ID以同样的方式:

df1['temp'] = df1['NAME'].astype(str)+df1['ID'].astype(str) 
df2['temp'] = df2['NAME'].astype(str)+df2['ID'].astype(str) 
df1[~df1['temp'].isin(df2['temp'])].drop('temp',1)