Вы можете создать DataFrame со старой и новой версией бок о бок с внешним объединением
>> df2 = pd.merge(df, updatedDf, on ='ID', how='outer', suffixes=['', '_update'])
Name Colour ID Compare Name_update Colour_update
0 Lisa Red Apple Lisa Purple
1 Anna Blue Banana NaN NaN
2 Anna Yellow Orange Anna Yellow
3 Max Green Pear NaN NaN
4 NaN NaN Grape NaN Peter Pink
Теперь вам нужно определить, как распознавать каждый из ваших дел:
- Если
Name
и Colour
равны NaN, запись является новой - Если
Name_updated
и Colour_updated
равны NaN, запись была удалена - Если
Name
и Colour
оба равны Name_updated
и Colour_updated
, запись не изменилась - Если
Name
и Name_updated
равны, но Color
и Colour_updated
не совпадают, цвет был изменен - И наоборот, если имя изменилось
- Если
Name
и Colour
не равны Name_updated
и Colour_updated
, вы еще не определили ожидаемое поведение
Помните, что это не учитывает крайние случаи, например, когда было удалено только одно поле или идентификаторы не являются уникальными
Вы можете инкапсулировать все эти условные выражения в функцию и использовать метод apply или просто сделать это с помощью copy-pasteвот так
df2.loc[df2[['Name', 'Colour']].isnull().any(axis=1), 'Compare'] = 'New entry'
df2.loc[df2[['Name_updated', 'Colour_updated']].isnull().any(axis=1), 'Compare'] = 'Entry deleted'
df2.loc[(~df2[['Name', 'Colour', 'Name_updated', 'Colour_updated']].isnull().any(axis=1)) & (df2['Name'] == df2['Name_updated']) & (df2['Colour'] == df2['Colour_updated']), 'Compare'] = 'No changes'
df2.loc[(~df2[['Name', 'Colour', 'Name_updated', 'Colour_updated']].isnull().any(axis=1)) & (df2['Name'] == df2['Name_updated']) & (df2['Colour'] != df2['Colour_updated']), 'Compare'] = 'Colour changed'
df2.loc[(~df2[['Name', 'Colour', 'Name_updated', 'Colour_updated']].isnull().any(axis=1)) & (df2['Name'] != df2['Name_updated']) & (df2['Colour'] == df2['Colour_updated']), 'Compare'] = 'Name changed'
df2.loc[(~df2[['Name', 'Colour', 'Name_updated', 'Colour_updated']].isnull().any(axis=1)) & (df2['Name'] != df2['Name_updated']) & (df2['Colour'] != df2['Colour_updated']), 'Compare'] = 'Name and colour changed'
Хотя это немного сложно, проверить, что ни одна из записей не является NaN
,cessary в последних 4 заявлениях.Сравнение с NaN
всегда верно, так что это немного безопаснее.
Принимайте новые значения везде, где вы можете
df2['Name'].update(df2['Name_updated'])
df2['Colour'].update(df2['Colour_updated'])
Используемый здесь метод Series.update пропускает строкигде значения, где удаляются автоматически.
В конце вы можете выбросить временные столбцы.
df2.drop(['Name_updated', 'Colour_updated'], axis=1, inplace=True)
Name Colour ID Compare
0 Lisa Purple Apple Colour changed
1 Anna Blue Banana Entry deleted
2 Anna Yellow Orange No changes
3 Max Green Pear Entry deleted
4 Peter Pink Grape New entry