Панды, сравнивающие фрейм данных с фреймом данных основной истины

#python #pandas #dataframe #comparison

Вопрос:

У меня есть фрейм данных, содержащий список неупорядоченных идентификаторов проектов и их соответствующих лидеров. Я хочу сравнить значения нового фрейма данных с основной истиной, чтобы убедиться, что все идентификаторы проекта в новом фрейме данных являются обоими; в основной истине и имеют одного и того же лидера. Иногда новый фрейм данных может иметь разные имена столбцов, но их всегда два и всегда означают одно и то же.

Например, фрейм данных основной истины (df_gt):

 Project ID          Leader
123                Owen Wilson
122                Samuel Jackson
145                Jack Black
134                Natalie Portman
 

В то время как новый фрейм данных может быть (df_new):

 Project             Leader
123                Owen Wilson
122                Henry Cavil
144                Natalie Portman
146                Jack Black
 

Моим желаемым результатом будет список всех отклонений от основной истины, которые содержатся в новом кадре данных. В этом случае:

ошибки == [[122, Генри Кэвил], [144, Натали Портман], [146, Джек Блэк]]

каков самый простой способ сделать это, чтобы разместить несколько потенциальных новых фреймов данных, каждый из которых имеет свои собственные соглашения об именовании столбцов, но те же предполагаемые значения.

Ответ №1:

Другое решение заключается в использовании .merge с indicator= :

 x = df1.merge(
    df2,
    left_on=["Project ID", "Leader"],
    right_on=["Project", "Leader"],
    indicator=True,
    how="right",
)

errors = (
    x.loc[x._merge.eq("right_only")]
    .apply(lambda x: [x["Project"], x["Leader"]], axis=1)
    .to_list()
)

print(errors)
 

С принтами:

 [[122, 'Henry Cavil'], [144, 'Natalie Portman'], [146, 'Jack Black']]
 

Комментарии:

1. Спасибо! Этот ответ — произведение искусства.

Ответ №2:

 df_1 = pd.DataFrame(data={'Project ID': [123, 122, 145, 134], 'Leader': ['Owen Wilson', 'Samuel Jackson',
                                                                       'Jack Black', 'Natalie Portman']})
df_2 = pd.DataFrame(data={'Project ID': [123, 122, 144, 146], 'Leader': ['Owen Wilson', 'Henry Cavil',
                                                                       'Natalie Portman', 'Jack Black']})

df_2['new'] = df_2['Project ID'].map(df_1.set_index('Project ID')['Leader'])
df_2 = df_2[(df_2['Leader']!=df_2['new'])]
print(df_2[['Project ID', 'Leader']].values.tolist())
 

Ответ №3:

Предполагая, что фреймы данных всегда имеют два столбца и расположены в том же порядке, как указано в OP, мы можем использовать MultiIndex.difference для поиска не совпадающих строк

 errs = pd.MultiIndex.from_frame(df_new)
         .difference(pd.MultiIndex.from_frame(df_gt))
 

 >>> list(errs)
[(122, 'Henry Cavil'), (144, 'Natalie Portman'), (146, 'Jack Black')]