Как сделать стиль SQL непересекающимся или установить разницу на двух объектах Pandas DataFrame?

Я пытаюсь использовать Pandas, чтобы решить проблему с помощью идиотского DBA, не делая резервную копию теперь разбитого набора данных, поэтому я пытаюсь найти различия между двумя столбцами. По причинам, в которые я не попаду, я использую Pandas, а не базу данных.

Что я хотел бы сделать, это:

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

Я хотел бы найти значения, которые не пересекаются.

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

В SQL это стандартная логика набора, выполняемая по-разному в зависимости от диалекта, но стандартная функция. Как я могу элегантно применить это в Pandas? Я хотел бы ввести некоторый код, но ничего, что у меня есть, даже отдаленно корректно. Это ситуация, в которой я не знаю, чего не знаю..... Pandas установил логику для пересечения и объединения, но ничего для дизъюнктной/установочной разницы.

Спасибо!

2 ответа

Вы можете использовать функцию 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'])


Здесь решение для нескольких столбцов, возможно, не очень эффективно, я хотел бы получить некоторые отзывы об этом быстрее:

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

licensed under cc by-sa 3.0 with attribution.