我有两个熊猫数据帧,它们有一些相同的行。
假设dataframe2是dataframe1的子集。
我怎么能得到dataframe1的行不在dataframe2?
df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5], 'col2' : [10, 11, 12, 13, 14]})
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12]})
df1
col1 col2
0 1 10
1 2 11
2 3 12
3 4 13
4 5 14
df2
col1 col2
0 1 10
1 2 11
2 3 12
预期结果:
col1 col2
3 4 13
4 5 14
一种方法是在两个dfs中存储一个内部合并表单的结果,然后我们可以简单地选择当一列的值不在这个公共值时的行:
In [119]:
common = df1.merge(df2,on=['col1','col2'])
print(common)
df1[(~df1.col1.isin(common.col1))&(~df1.col2.isin(common.col2))]
col1 col2
0 1 10
1 2 11
2 3 12
Out[119]:
col1 col2
3 4 13
4 5 14
EDIT
你已经发现的另一个方法是使用isin,它会生成NaN行,你可以删除:
In [138]:
df1[~df1.isin(df2)].dropna()
Out[138]:
col1 col2
3 4 13
4 5 14
然而,如果df2不以同样的方式开始行,那么这将不起作用:
df2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11, 12,13]})
将产生整个df:
In [140]:
df1[~df1.isin(df2)].dropna()
Out[140]:
col1 col2
0 1 10
1 2 11
2 3 12
3 4 13
4 5 14
我认为那些包含合并的答案是极其缓慢的。因此,我建议另一种方法来获得两个数据框架之间不同的行:
df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5], 'col2' : [10, 11, 12, 13, 14]})
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12]})
免责声明:如果您对两个数据框架不同的特定列感兴趣,那么我的解决方案是有效的。如果您只对那些所有列都相等的行感兴趣,则不要使用这种方法。
比方说,col1是一种ID,你只想获取那些不包含在两个数据框架中的行:
ids_in_df2 = df2.col1.unique()
not_found_ids = df[~df['col1'].isin(ids_in_df2 )]
就是这样。你得到的数据框架只包含那些col1在两个数据框架中都不明显的行。