Найти строки в фрейме данных, которые не доступны в другом фрейме данных, исключая значения одного столбца

#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)