3 回答

TA贡献1921条经验 获得超9个赞
merge
您可以merge使用indicator=True并仅包含标记为 的那些行'left_only'。
res = df1.merge(df2.drop('val_a', 1), how='left', on=['id', 'nr'], indicator=True)
res = res.loc[res['_merge'] == 'left_only'].drop('_merge', 1)
print(res)
id nr val_a
2 1 93 24
4 2 92 34
5 2 93 35
6 3 91 44
8 3 93 42
该解决方案很容易适应任何条件,具体取决于'left_only'、'right_only'或'both'。

TA贡献1858条经验 获得超8个赞
isin将merge列压缩后的方法1tuple
df1[~df1[['id','nr']].apply(tuple,1).isin(df2[['id','nr']].apply(tuple,1))]
Out[43]:
id nr val_a
2 1 93 24
4 2 92 34
5 2 93 35
6 3 91 44
8 3 93 42
方法二numpy广播
s1=df1[['id','nr']].values
s2=df2[['id','nr']].values
df1[~np.any(np.all(s1==s2[:,None],-1),0)]
Out[64]:
id nr val_a
2 1 93 24
4 2 92 34
5 2 93 35
6 3 91 44
8 3 93 42
我的方法计时
%timeit df1[~df1[['id','nr']].apply(tuple,1).isin(df2[['id','nr']].apply(tuple,1))]
100 loops, best of 3: 3.67 ms per loop
def m2():
s1 = df1[['id', 'nr']].values
s2 = df2[['id', 'nr']].values
return df1[~np.any(np.all(s1 == s2[:, None], -1), 0)]
%timeit m2()
1000 loops, best of 3: 926 µs per loop

TA贡献1847条经验 获得超7个赞
能inner join解决你的问题吗?获取与条件匹配的参数的索引,然后将其过滤掉。reset_index()如果你想这样做,你只需要事后去做。
df3 = df1.merge(df2, how = 'inner', on = ['id','nr']).reset_index()
id_list = df3['id'].tolist()
df4 = df1[~df1['id'].isin(id_list)]
添加回答
举报