Pandas从一个数据框中移除另一个数据框的所有元素

1 投票
3 回答
3563 浏览
提问于 2025-04-18 02:15

我想找出两个数据表之间的差异,也就是在第一个数据表(df1)中有,但在第二个数据表(df2)中没有的元素。两个数据表的结构是一样的。

假设df1包含

col1 col2 col3 col4
A    B    C    D
A    C    D    D

而df2包含

col1 col2 col3 col4
A    D    D    D
A    B    D    D

我想要的是在df1中找出那些在df2中没有对应项的记录,条件是要看col1和col2这两列是否匹配。所以在这个例子中,预期的结果就是df1的第二行。

A    C    D    D

我尝试了不同的isin用法,但一直找不到有效的方法。我还试过这个链接,但那只适用于单列。

3 个回答

0

我不知道这样做是否高效,但经过几个小时的尝试,我找到了一种方法。这个方法首先是重新设置数据框的索引,让你关心的列作为索引。

df1.set_index(['col1', 'col2'], inplace=True)
df2.set_index(['col1', 'col2'], inplace=True)

df1[df1.index.map(lambda x: x not in df2.index)]
1

我知道这个问题很老套了。不过如果我在谷歌上搜索这个问题,它总是排在最前面。如果两个数据表中都有一列,且这些列里的值都是独一无二的,可以这样做:

  uniq__value_list = df1[col1].tolist()
  df3 = df2[~df.col1.isin(uniq__value_list)]

现在,第三个数据表将会包含那些在第一个数据表中但不在第二个数据表中的值。

2

使用 isin 的问题在于,如果你使用的是数据框(DataFrame),那么索引也必须匹配。我不知道你的索引是什么,但如果在 col1 和 col2 相等的情况下,索引不同,它仍然会返回一个负结果。

把你的第二个数据框转换成列表会让它正常工作(因为这样就去掉了索引)。isin 会分别匹配两个列,但通过 all(axis-1) 你可以过滤到两个列都匹配的情况。

sub = ['col1', 'col2']
mask = df1[sub].isin(df2[sub].to_dict(outtype='list')).all(axis=1)

df1[~mask]

  col1 col2 col3 col4
1    A    C    D    D

撰写回答