#python #pandas #dataframe
#python #панды #фрейм данных
Вопрос:
У меня есть 2 фрейма данных с одинаковыми именами столбцов:
#df1
col_1 col_2 col_3
1 10 100
2 20 40
3 30 50
#df2
col_1 col_2 col_3
5 10 200
3 20 500
3 30 700
Я хочу сравнить эти 2 фрейма данных, основанные только на col_1 и col_2, и найти строки в df1 со значениями в col_1 и col_2, которых нет в df2
вот желаемый результат из приведенного выше примера:
#df
col_1 col_2 col_3
3 30 50
Я попробовал этот код, но он сравнивает всю строку, и я хочу сравнить только col_1 и col_2:
df = df1.merge(df2, how = 'outer',indicator=True).loc[lambda x : x['_merge']=='left_only']
Комментарии:
1. » Я пробовал этот код, но он сравнивает всю строку, и я хочу сравнить только col_1 и col_2 » затем поместите только эти столбцы в слияние:
df1.merge(df2, on = ['col_1','col_2'], how = 'outer',indicator=True).loc....
Ответ №1:
Уникальны ли пары col_1, col_2 в обоих фреймах данных?
Вы можете сделать:
join_cols = ['col_1', 'col_2']
merged = df1[join_cols].join(df2.set_index(join_cols), on=join_cols)
not_in_df2 = merged.col_3.isnull()
Если индекс соединения уникален, то not_in_df1
он будет выровнен с df2
. В противном случае вы можете выполнить следующее, что работает в обоих случаях
not_in_df2 = merged.index[not_in_df1].unique()
Наконец,
df1.loc[not_in_df2]
Редактировать:
Возможно, лучший способ:
index = pd.MultiIndex.from_arrays([df2.col_1, df2.col_2]).unique()
not_in_df2 = index.get_indexer([df1.col_1, df1.col_2]) == -1
Ответ №2:
Если вы хотите использовать функцию Pandas merge
, я бы предложил следующее решение:
df = df1.merge(df2, how='inner', on = ['col_1', 'col_2'], suffixes=('', 'b'))
df = df.drop(df.columns.difference(df1.columns), axis = 1)
Если нет, вот более простое решение вашей проблемы:
df = df1.loc[np.where((df1["col_1"] == df2["col_1"])amp;(df1["col_2"] == df2["col_2"]), True, False)]
Если вы также хотите сбросить номера строк в результирующем фрейме данных, вы можете просто использовать:
df = df.reset_index(drop = True)