Как по-настоящему сравнить два кадра данных на основе ключевого столбца?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как по-настоящему сравнить два кадра данных на основе ключевого столбца?

Сообщение Anonymous »

Мои входные данные — это два фрейма данных:

Код: Выделить всё

import pandas as pd

df_having = pd.DataFrame({'ID': ['ID_01', 'ID_01', 'ID_01', 'ID_01', 'ID_02', 'ID_03', 'ID_03', 'ID_05', 'ID_06', 'ID_06'], 'NAME': ['A', 'A', 'A', 'A', 'E', 'B', 'B', 'E', 'A', 'A'], 'TYPE': ['A', 'A', 'B', 'A', 'C', 'A', 'B', 'F', 'A', 'A'], 'CATEGORY': [1, 1, 3, 3, 3, 1, 2, 1, 1, 1]})
df_tohave = pd.DataFrame({'ID': ['ID_01', 'ID_01', 'ID_02', 'ID_02', 'ID_03', 'ID_03', 'ID_03', 'ID_04', 'ID_05'], 'NAME': ['A', 'A', 'A', 'A', 'B', 'B', 'E', 'A', 'D'], 'TYPE': ['A', 'B', 'C', 'C', 'A', 'A', 'B', 'D', 'G'], 'CATEGORY': [1, 2, 1, 2, 1, 2, 3, 3, 2]})
Я пытаюсь выполнить сравнение на основе столбца «ID», чтобы в итоге получить третий кадр данных (в самом правом углу изображения ниже):
Изображение

Код: Выделить всё

df_having
отражает реальную ситуацию в системе, а df_tohave — это то, что должно быть.
Флаг может иметь следующие значения:
  • NO_ACTION: «ID» имеет правильные «NAME», «TYPE» и «CATEGORY» в df_having
    < li>TO_CREATE: идентификатор отсутствует в df_having и существует в df_tohave
  • TO_UPDATE: идентификатор существует в df_having, но в хотя бы одно из полей «NAME», «TYPE» и «CATEGORY» неверно.
  • TO_DELETE: «ID» существует в df_having, а не в df_tohave
ПОЛЯ — это просто поля, на которые указывает ФЛАГ.
Когда создавая кадр данных сравнения, если флаг «TO_DELETE», мы извлекаем строку из df_having, в противном случае мы получаем ее из df_tohave.
Я попробовал, но результирующий фрейм данных содержит 34 строки, хотя должно быть 13, и большинство флагов неверны.

Код: Выделить всё

import functools

cols = ['NAME', 'TYPE', 'CATEGORY']
df_diff = functools.reduce(lambda left, right: pd.merge(left, right, on='ID', how='outer', suffixes=('_having', '_tohave')),
[df_having[['ID'] + cols], df_tohave[['ID'] + cols]])

for col in cols:
df_diff[f'{col}_diff'] = df_diff[f'{col}_having'] != df_diff[f'{col}_tohave']

df_diff['FIELDS'] = df_diff[[f'{col}_diff' for col in cols]].dot(pd.Index(cols) + ' & ').str.strip(' & ')
df_diff = df_diff[df_diff['FIELDS'] != ''].assign(FLAG='TO_UPDATE')

df_comparison = pd.concat([merged, df_diff[['ID', 'NAME_tohave', 'TYPE_tohave', 'CATEGORY_tohave', 'FLAG', 'FIELDS']].rename(columns={
'NAME_tohave': 'NAME', 'TYPE_tohave': 'TYPE', 'CATEGORY_tohave': 'CATEGORY'})]).drop(columns='_merge').reset_index(drop=True)
Ребята, вы знаете, что я делаю не так? Или у вас есть предложение по решению этой проблемы?

Подробнее здесь: https://stackoverflow.com/questions/790 ... key-column
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»