如何从另一个pandas数据框中减去一行?

Rom*_*man 11 python merge pandas

我想要做的操作类似于合并.例如,通过inner合并,我们得到一个数据帧,其中包含第一个和第二个数据帧中存在的行.通过outer合并,我们得到一个数据帧,该数据帧在第二个数据帧的第一个OR中出现.

我需要的是一个数据框,其中包含第一个数据框中存在的行而第二个数据框中不存在的行?有一种快速而优雅的方式吗?

小智 12

考虑以下:

  1. df_one是第一个DataFrame
  2. df_two是第二个DataFrame

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

解决方案:按索引 df = df_one[~df_one.index.isin(df_two.index)]

index可以替换为您希望排除的必需.在上面的例子中,我使用了index作为两个数据帧之间的引用

此外,您还可以使用更复杂的查询使用boolean pandas.Series来解决上述问题.


Kar*_* D. 10

怎么样以下的东西?

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
Run Code Online (Sandbox Code Playgroud)

只要存在非键的通常命名的列,您就可以让添加的on sufffex执行工作(如果没有非键的公共列,那么您可以创建一个临时使用... df1['common'] = 1并且df2['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
Run Code Online (Sandbox Code Playgroud)

或者你可以使用,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
Run Code Online (Sandbox Code Playgroud)


小智 5

如果您的非索引列包含带有 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
Run Code Online (Sandbox Code Playgroud)

2112 中的问题团队在任一表中都没有 foo 的值。因此,这里的左连接将错误地返回在两个 DataFrame 中都匹配的那一行,因为它不存在于右侧的 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
Run Code Online (Sandbox Code Playgroud)

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

  Problem  2112    NaN    NaN     yes     yes
Run Code Online (Sandbox Code Playgroud)