我有两个熊猫数据帧,它们有一些相同的行。

假设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

当前回答

这里有另一种解决方法:

df1[~df1.index.isin(df1.merge(df2, how='inner', on=['col1', 'col2']).index)]

Or:

df1.loc[df1.index.difference(df1.merge(df2, how='inner', on=['col1', 'col2']).index)]

其他回答

我认为那些包含合并的答案是极其缓慢的。因此,我建议另一种方法来获得两个数据框架之间不同的行:

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在两个数据框架中都不明显的行。

假设索引在数据帧中是一致的(不考虑实际的col值):

df1[~df1.index.isin(df2.index)]

你可以使用isin(dict)方法:

In [74]: df1[~df1.isin(df2.to_dict('l')).all(1)]
Out[74]:
   col1  col2
3     4    13
4     5    14

解释:

In [75]: df2.to_dict('l')
Out[75]: {'col1': [1, 2, 3], 'col2': [10, 11, 12]}

In [76]: df1.isin(df2.to_dict('l'))
Out[76]:
    col1   col2
0   True   True
1   True   True
2   True   True
3  False  False
4  False  False

In [77]: df1.isin(df2.to_dict('l')).all(1)
Out[77]:
0     True
1     True
2     True
3    False
4    False
dtype: bool

你也可以concat df1, df2:

x = pd.concat([df1, df2])

然后删除所有重复项:

y = x.drop_duplicates(keep=False, inplace=False)

假设你有两个数据框架,df_1和df_2有多个字段(column_names),你想在df_1中找到那些不在df_2中的条目。Fields_x, fields_y),执行以下步骤。

步骤1。将列key1和key2分别添加到df_1和df_2中。

步骤2。合并数据帧,如下所示。Field_x和field_y是我们想要的列。

步骤3。只选择df_1中key1不等于key2的行。

第四。删除key1和key2。

这种方法将解决你的问题,即使有大数据集也能快速工作。我已经尝试了超过1,000,000行的数据框架。

df_1['key1'] = 1
df_2['key2'] = 1
df_1 = pd.merge(df_1, df_2, on=['field_x', 'field_y'], how = 'left')
df_1 = df_1[~(df_1.key2 == df_1.key1)]
df_1 = df_1.drop(['key1','key2'], axis=1)