4

我有一个 python pandas DataFrame 问题。有两个包含记录的 DataFrame,df1df2。它们包含以下值:

df1:
   pkid  start   end
0     0   2005  2005
1     1   2006  2006
2     2   2007  2007
3     3   2008  2008
4     4   2009  2009

df2:
   pkid  start   end
0     3   2008  2008
1   NaN   2009  2009
2   NaN   2010  2010

我希望将记录 w/index=2 与df2隔离开来。换句话说,我正在寻找df2的所有记录,其中df1中没有匹配的记录,其中只考虑开始和结束列值。谢谢!

4

2 回答 2

3

此操作称为antijoin (▷)关系代数和 SQL。我试图为此找到本机熊猫操作,但一无所获。

但是你可以用功能的方式来做,不知道性能:)

>>> t1 = df1[["start", "end"]]
>>> t2 = df2[["start", "end"]]
>>> f = t2.apply(lambda x2: t1.apply(lambda x1: x1.isin(x2).all(), axis=1).any(), axis=1)
>>> df2[~f]
    end  pkid  start
2  2010   NaN   2010

更新:在 SQL 中,可以通过不同的方式完成,例如not exists

select *
from df2
where not exists (select * from df1 where df1.start = df2.start and df1.end = df2.end)

left outer joinwhere子句:

select *
from df1
    left outer join df1 on df1.start = df2.start and df1.end = df1.end
where df1.<key> is null

最后一个可以在 pandas 中实现merge

>>> m = pd.merge(df2, df1, how='left', on=['end','start'], suffixes=['','_r'])
>>> df2[m['pkid_r'].isnull()]
    end  pkid  start
2  2010   NaN   2010
于 2013-10-25T20:45:04.713 回答
0

您可以向框架添加一个键,然后使用“isin”功能

df1['key'] = df1.apply(lambda r: str(r['start']) + str(r['end']), axis=1)
df2['key'] = df2.apply(lambda r: str(int(r['start'])) + str(int(r['end'])), axis=1)

df2.key.isin(df1.key.tolist())
0    True
1    True
2    False


df2[~df2.key.isin(df1.key.tolist())]
pkid  start   end
2   NaN   2010  2010
于 2013-10-25T20:18:59.773 回答