Ответ 1
Одним из возможных решений вашей проблемы будет использование merge. Проверка наличия любой строки (всех столбцов) из другого фрейма данных (df2) в df1 эквивалентна определению пересечения двух данных. Это можно выполнить, используя следующую функцию:
pd.merge(df1, df2, on=['A', 'B', 'C', 'D'], how='inner')
Например, если df1 был
A B C D
0 0.403846 0.312230 0.209882 0.397923
1 0.934957 0.731730 0.484712 0.734747
2 0.588245 0.961589 0.910292 0.382072
3 0.534226 0.276908 0.323282 0.629398
4 0.259533 0.277465 0.043652 0.925743
5 0.667415 0.051182 0.928655 0.737673
6 0.217923 0.665446 0.224268 0.772592
7 0.023578 0.561884 0.615515 0.362084
8 0.346373 0.375366 0.083003 0.663622
9 0.352584 0.103263 0.661686 0.246862
и df2 определяется как:
A B C D
0 0.259533 0.277465 0.043652 0.925743
1 0.667415 0.051182 0.928655 0.737673
2 0.217923 0.665446 0.224268 0.772592
3 0.023578 0.561884 0.615515 0.362084
4 0.346373 0.375366 0.083003 0.663622
5 2.000000 3.000000 4.000000 5.000000
6 14.000000 15.000000 16.000000 17.000000
Функция pd.merge(df1, df2, on=['A', 'B', 'C', 'D'], how='inner')
производит:
A B C D
0 0.259533 0.277465 0.043652 0.925743
1 0.667415 0.051182 0.928655 0.737673
2 0.217923 0.665446 0.224268 0.772592
3 0.023578 0.561884 0.615515 0.362084
4 0.346373 0.375366 0.083003 0.663622
Результатом являются все строки (все столбцы), которые находятся как в df1, так и в df2.
Мы также можем изменить этот пример, если столбцы не совпадают в df1 и df2 и просто сравнивают значения строк, которые одинаковы для подмножества столбцов. Если мы изменим исходный пример:
df1 = pd.DataFrame(np.random.rand(10,4),columns=list('ABCD'))
df2 = df1.ix[4:8]
df2.reset_index(drop=True,inplace=True)
df2.loc[-1] = [2, 3, 4, 5]
df2.loc[-2] = [14, 15, 16, 17]
df2.reset_index(drop=True,inplace=True)
df2 = df2[['A', 'B', 'C']] # df2 has only columns A B C
Затем мы можем посмотреть на общие столбцы, используя common_cols = list(set(df1.columns) & set(df2.columns))
между двумя файлами данных, затем слить:
pd.merge(df1, df2, on=common_cols, how='inner')
РЕДАКТИРОВАТЬ: Новый вопрос (комментарии), идентифицировавший строки из df2, которые также присутствовали в первом фрейме данных (df1), можно взять результат pd.merge() и затем опустить строки из df2, которые также присутствуют в df1
Я не знаю простого способа выполнить задачу по удалению строк из df2, которые также присутствуют в df1. Тем не менее, вы можете использовать следующее:
ds1 = set(tuple(line) for line in df1.values)
ds2 = set(tuple(line) for line in df2.values)
df = pd.DataFrame(list(ds2.difference(ds1)), columns=df2.columns)
Вероятно, существует лучший способ выполнить эту задачу, но я не знаю о таком методе/функции.
EDIT 2: Как удалить строки из df2, которые также присутствуют в df1, как показано в ответе @WR.
Предоставленный метод df2[~df2['A'].isin(df12['A'])]
не учитывает все типы ситуаций. Рассмотрим следующие DataFrames:
df1:
A B C D
0 6 4 1 6
1 7 6 6 8
2 1 6 2 7
3 8 0 4 1
4 1 0 2 3
5 8 4 7 5
6 4 7 1 1
7 3 7 3 4
8 5 2 8 8
9 3 2 8 4
df2:
A B C D
0 1 0 2 3
1 8 4 7 5
2 4 7 1 1
3 3 7 3 4
4 5 2 8 8
5 1 1 1 1
6 2 2 2 2
df12:
A B C D
0 1 0 2 3
1 8 4 7 5
2 4 7 1 1
3 3 7 3 4
4 5 2 8 8
Использование вышеуказанных DataFrames с целью удаления строк из df2, которые также присутствуют в df1, приведет к следующему:
A B C D
0 1 1 1 1
1 2 2 2 2
Строки (1, 1, 1, 1) и (2, 2, 2, 2) находятся в df2, а не в df1. К сожалению, использование предоставленного метода (df2[~df2['A'].isin(df12['A'])]
) приводит к:
A B C D
6 2 2 2 2
Это происходит потому, что значение 1 в столбце A найдено как в пересечении DataFrame (т.е. (1, 0, 2, 3)) и df2 и, таким образом, удаляет оба (1, 0, 2, 3) и (1, 1, 1, 1). Это непреднамеренно, так как строка (1, 1, 1, 1) не находится в df1 и не должна удаляться.
Я думаю, что следующее будет служить решением. Он создает фиктивный столбец, который позже используется для подмножества DataFrame с желаемыми результатами:
df12['key'] = 'x'
temp_df = pd.merge(df2, df12, on=df2.columns.tolist(), how='left')
temp_df[temp_df['key'].isnull()].drop('key', axis=1)