Pandas:通过多列查找另一个DataFrame中不存在的行

Pek*_*kka 22 python join pandas

和这个python pandas一样:如何在一个数据帧中找到行但在另一个数据帧中找不到? 但有多列

这是设置:

import pandas as pd

df = pd.DataFrame(dict(
    col1=[0,1,1,2],
    col2=['a','b','c','b'],
    extra_col=['this','is','just','something']
))

other = pd.DataFrame(dict(
    col1=[1,2],
    col2=['b','c']
))
Run Code Online (Sandbox Code Playgroud)

现在,我想选择其他行中df不存在的行.我想用col1和做选择col2

在SQL中我会这样做:

select * from df 
where not exists (
    select * from other o 
    where df.col1 = o.col1 and 
    df.col2 = o.col2
)
Run Code Online (Sandbox Code Playgroud)

在熊猫我可以做这样的事情,但感觉非常难看.如果df具有id-column,则可以避免部分丑陋,但并不总是可用.

key_col = ['col1','col2']
df_with_idx = df.reset_index()
common = pd.merge(df_with_idx,other,on=key_col)['index']
mask = df_with_idx['index'].isin(common)

desired_result =  df_with_idx[~mask].drop('index',axis=1)
Run Code Online (Sandbox Code Playgroud)

那么也许有一些更优雅的方式?

EdC*_*ica 29

由于0.17.0有一个新的indicator参数,您可以传递给merge它,它将告诉您行是仅出现在左侧,右侧还是两侧:

In [5]:
merged = df.merge(other, how='left', indicator=True)
merged

Out[5]:
   col1 col2  extra_col     _merge
0     0    a       this  left_only
1     1    b         is       both
2     1    c       just  left_only
3     2    b  something  left_only

In [6]:    
merged[merged['_merge']=='left_only']

Out[6]:
   col1 col2  extra_col     _merge
0     0    a       this  left_only
2     1    c       just  left_only
3     2    b  something  left_only
Run Code Online (Sandbox Code Playgroud)

因此,您现在可以通过仅选择'left_only'行来过滤合并的df

  • 感谢您回到这里。您可以使用 df.merge(other, how='left', Indicator=True).query('_merge == "left_only"')` 在一行中完成此操作,但不知道这是否更好。 (2认同)
  • @Pekka:+ 在一行中回到原来的左边:`df.merge(other, how='left', indicator=True).query('_merge == "left_only"').drop(['_merge' ],轴=1)` (2认同)

gre*_*ata 6

有趣的

cols = ['col1','col2']
#get copies where the indeces are the columns of interest
df2 = df.set_index(cols)
other2 = other.set_index(cols)
#Look for index overlap, ~
df[~df2.index.isin(other2.index)]
Run Code Online (Sandbox Code Playgroud)

返回:

    col1 col2  extra_col
0     0    a       this
2     1    c       just
3     2    b  something
Run Code Online (Sandbox Code Playgroud)

看起来更优雅一点...

  • 如果您将索引设置为那些列,您可以使用 [`difference`](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Index.difference.html#pandas.Index.difference) 来达到相同的结果 (2认同)