如何在两个Pandas DataFrame对象上进行SQL风格的差集?

7 投票
2 回答
3591 浏览
提问于 2025-04-17 13:15

我正在尝试使用Pandas来解决一个问题,这个问题是因为一个不靠谱的数据库管理员没有备份现在崩溃的数据集,所以我需要找出两列之间的差异。由于一些原因,我选择使用Pandas而不是数据库。

我想做的是,给定:

Dataset A = [A, B, C, D, E]  
Dataset B = [C, D, E, F]

我想找出那些不重叠的值。

Dataset A!=B = [A, B, F]

在SQL中,这属于标准的集合逻辑,不同的SQL方言有不同的实现方式,但都是标准功能。那我该如何优雅地在Pandas中实现呢?我很想输入一些代码,但我现在的代码都不太对。这种情况让我感到困惑,我不知道自己到底缺少了什么……Pandas有集合逻辑来处理交集和并集,但没有处理不重叠或集合差异的功能。

谢谢!

2 个回答

0

这是一个处理多个列的解决方案,可能效率不是很高,我很想听听大家的意见,看看怎么能让这个过程更快:

input = pd.DataFrame({'A': [1, 2, 2, 3, 3], 'B': ['a', 'a', 'b', 'a', 'c']})
limit = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'c']})


def set_difference(input_set, limit_on_set):
    limit_on_set_sub = limit_on_set[['A', 'B']]
    limit_on_tuples = [tuple(x) for x in limit_on_set_sub.values]
    limit_on_dict = dict.fromkeys(limit_on_tuples, 1)

    entries_in_limit = input_set.apply(lambda row:
        (row['A'], row['B']) in limit_on_dict, axis=1)

    return input_set[~entries_in_limit]

 >>> set_difference(input, limit)

  item  user
1    a     2
3    a     3
9

你可以使用 set.symmetric_difference 这个函数:

In [1]: df1 = DataFrame(list('ABCDE'), columns=['x'])

In [2]: df1
Out[2]:
   x
0  A
1  B
2  C
3  D
4  E

In [3]: df2 = DataFrame(list('CDEF'), columns=['y'])

In [4]: df2
Out[4]:
   y
0  C
1  D
2  E
3  F

In [5]: set(df1.x).symmetric_difference(df2.y)
Out[5]: set(['A', 'B', 'F'])

撰写回答