2014-04-25 166 views
6

我想要做的操作与合并类似。例如,通过inner合并,我们得到一个数据框,其中包含第一个数据框和第二个数据框中存在的行。通过outer合并,我们可以得到一个数据帧,无论是在第二个数据帧中的第一个OR中。如何从另一个熊猫数据框中减去一行?

我需要的是一个数据框,其中包含第一个数据框中存在的行,而不存在于第二个数据框中?有没有一个快速和优雅的方式来做到这一点?

+0

how ='left'?当然这不是你想要的(考虑到你的SO分数,它必须比这更复杂) –

+0

左或右合并为我提供了一个数据框,其中包含存在于其中一个数据框中的行。但我需要一个数据框,其中包含存在于一个数据框中的行,而不存在于另一个数据框中。 – Roman

+0

如果它只是一个合并键,那么你可以用'isin'和'〜'做它 –

回答

6

下面的情况如何?

print df1 

    Team Year foo 
0 Hawks 2001 5 
1 Hawks 2004 4 
2 Nets 1987 3 
3 Nets 1988 6 
4 Nets 2001 8 
5 Nets 2000 10 
6 Heat 2004 6 
7 Pacers 2003 12 

print df2 

    Team Year foo 
0 Pacers 2003 12 
1 Heat 2004 6 
2 Nets 1988 6 

只要有一个非键通常称为栏,可以让加在sufffexes做的工作(如果没有非关键共性列,那么你可以创建一个临时使用.. 。df1['common'] = 1df2['common'] = 1):

new = df1.merge(df2,on=['Team','Year'],how='left') 
print new[new.foo_y.isnull()] 

    Team Year foo_x foo_y 
0 Hawks 2001  5 NaN 
1 Hawks 2004  4 NaN 
2 Nets 1987  3 NaN 
4 Nets 2001  8 NaN 
5 Nets 2000  10 NaN 

或者你可以使用isin但你必须创建一个键:

df1['key'] = df1['Team'] + df1['Year'].astype(str) 
df2['key'] = df1['Team'] + df2['Year'].astype(str) 
print df1[~df1.key.isin(df2.key)] 

    Team Year foo   key 
0 Hawks 2001 5 Hawks2001 
2 Nets 1987 3 Nets1987 
4 Nets 2001 8 Nets2001 
5 Nets 2000 10 Nets2000 
6 Heat 2004 6 Heat2004 
7 Pacers 2003 12 Pacers2003 
4

您可以运行进军电子商务如果您的非索引列具有带有NaN的单元格,则会出现错误。

print df1 

    Team Year foo 
0 Hawks 2001 5 
1 Hawks 2004 4 
2 Nets 1987 3 
3 Nets 1988 6 
4 Nets 2001 8 
5 Nets 2000 10 
6 Heat 2004 6 
7 Pacers 2003 12 
8 Problem 2112 NaN 


print df2 

    Team Year foo 
0 Pacers 2003 12 
1 Heat 2004 6 
2 Nets 1988 6 
3 Problem 2112 NaN 

new = df1.merge(df2,on=['Team','Year'],how='left') 
print new[new.foo_y.isnull()] 

    Team Year foo_x foo_y 
0 Hawks 2001  5 NaN 
1 Hawks 2004  4 NaN 
2 Nets 1987  3 NaN 
4 Nets 2001  8 NaN 
5 Nets 2000  10 NaN 
6 Problem 2112 NaN NaN 

的问题球队在2112有在任一表foo没有价值。因此,这里的左连接将错误地返回与DataFrame中相匹配的那一行,因为它们不存在于正确的DataFrame中。

解决方案:

我做的是一个独特的列添加到数据框内部,并为所有行的值。然后,当您加入时,您可以检查该列是否为NaN,以便内部表在外部表中查找唯一记录。

df2['in_df2']='yes' 

print df2 

    Team Year foo in_df2 
0 Pacers 2003 12  yes 
1 Heat 2004 6  yes 
2 Nets 1988 6  yes 
3 Problem 2112 NaN  yes 


new = df1.merge(df2,on=['Team','Year'],how='left') 
print new[new.in_df2.isnull()] 

    Team Year foo_x foo_y in_df1 in_df2 
0 Hawks 2001  5 NaN  yes  NaN 
1 Hawks 2004  4 NaN  yes  NaN 
2 Nets 1987  3 NaN  yes  NaN 
4 Nets 2001  8 NaN  yes  NaN 
5 Nets 2000  10 NaN  yes  NaN 

NB。问题行现在被正确过滤掉了,因为它具有in_df2的值。

Problem 2112 NaN NaN  yes  yes 
+0

非常好,这对我来说工作得很好。 – Dirk

3

考虑跟进:

  1. df_one是第一个数据帧
  2. df_two是第二个数据帧

目前在第一数据帧不在第二数据帧

解决方案:指数 df = df_one[~df_one.index.isin(df_two.index)]

指数可以通过要求在你希望做排除更换。 在上面的示例中,我已将索引用作两个数据帧之间的参考

此外,还可以使用布尔熊猫使用更复杂的查询。以上系列解决。

相关问题