我有两个数据帧,第二个是第一个的子集。现在如何查找第二个数据帧中未包含的第一个数据帧的部分?例如:
new_dataframe_1
A B C D
1 a b c d
2 e f g h
3 i j k l
4 m n o p
new_dataframe_2
A B C D
1 a b c d
3 i j k l
new_dataframe_3 = not intersection of new_dataframe_1 and new_dataframe_2
A B C D
2 e f g h
4 m n o p
谢谢你的帮助!
编辑:我最初称交叉路口为工会,但此后对此进行了更改。
最佳答案
嗯,一种实现方法是使用isin
(但是您也可以使用merge
命令来实现它...我都展示了这两个示例)。例如:
>>> df1
A B C D
0 a b c d
1 e f g h
2 i j k l
3 m n o p
>>> df2
A B C D
0 a b c d
1 i j k l
>>> df1[~df1.isin(df2.to_dict('list')).all(axis=1)]
A B C D
1 e f g h
3 m n o p
解释。
isin
可以检查是否使用多列,如果您将其输入字典:>>> df2.to_dict('list')
{'A': ['a', 'i'], 'C': ['c', 'k'], 'B': ['b', 'j'], 'D': ['d', 'l']}
然后
isin
将创建一个booleen df,我可以用它来选择所需的列(在这种情况下,需要所有列都匹配,然后使用~
取反):>>> df1.isin(df2.to_dict('list'))
A B C D
0 True True True True
1 False False False False
2 True True True True
3 False False False False
在特定示例中,我们不需要为数据帧的dict版本提供
isin
,因为我们只需查看A列即可识别有效行:>>> df1[~df1['A'].isin(df2['A'])]
A B C D
1 e f g h
3 m n o p
您也可以使用
merge
做到这一点。在子集数据框中创建一个唯一列。合并时,较大数据框中的唯一行将为您创建的列带有NaN
:>>> df2['test'] = 1
>>> new = df1.merge(df2,on=['A','B','C','D'],how='left')
>>> new
A B C D test
0 a b c d 1
1 e f g h NaN
2 i j k l 1
3 m n o p NaN
因此,选择test == NaN的行并删除test列:
>>> new[new.test.isnull()].drop('test',axis=1)
A B C D
1 e f g h
3 m n o p
编辑: @ user3654387指出,合并方法对大型数据帧的性能要好得多。
关于Python 2.7与Pandas : How does one recover the non intersecting parts of two dataframes?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23851487/