Сравнить несколько значений из DataFrame с одной строкой из другого.

Вопрос или проблема

Я пытаюсь сравнить значения адресов на предмет неточностей, например, данные по нескольким записям, как показано ниже:

Ссылка Квартира Адрес Почтовый индекс
AS097 NaN 00 Name Road BH1 4HB
AS097 Квартира 1 Название здания 00 Name Road BH1 4HB
AS097 Квартира 2 Название здания 00 Name Rd BH1 4HB
AS097 Квартира 3 Название здания 00 Name Road BH1 4HB
AS097 Квартира 4 Название здания 00 Name Road BH1 4HB
AS097 Квартира 5 Название здания 00 Name Road BH1 4HX
HO056 NaN 23 Street Road XG9 9GX

У меня есть фрейм данных, где я сохраняю все “основные” адреса, проверяя, пуст ли столбец Квартира:

main_address = df['Apartment'].isnull()

df_st = pd.DataFrame({'Reference':df[main_address].Reference, 'Address':df[main_address].Address, 'PostCode':df[main_address].PostCode})

df_st будет выглядеть так:

Ссылка Квартира Адрес Почтовый индекс
AS097 NaN 00 Name Road BH1 4HB
HO056 NaN 23 Street Road XG9 9GX

df содержит более 1K записей, но df_st, содержащий “основной” адрес, заканчивается примерно на 200 записях.

Я пытаюсь создать новый DataFrame, где смогу определить, где записи не совпадают, сравнивая df с df_st.

ПРОБЛЕМА

Я пробую следующее:

# Очистить значения ссылок
refs_list = df['Reference'].str.split("https://datascience.stackexchange.com/").str[0]
df['Reference'] = refs_list

# Создать новый столбец с названием issues и отметить, если ссылки совпадают
df['issues'] = np.where(df['Reference'] == df_st['Reference'], 'True', 'False')

Я хочу сделать то же самое для Address и PostCode, но, к сожалению, это не сработало, так как df и df_st не имеют одинаковой формы.

Мне сложно найти способ достичь сравнения между двумя DataFrame df и df_st.

Я хочу сравнить все совпадающие значения строк Reference из df с соответствующими значениями из df_st и, если они не совпадают, создать новый столбец с названием Issues и сохранить там конфликтующие столбцы.

МОЙ ЖЕЛАЕМЫЙ РЕЗУЛЬТАТ

Учитывая вышеприведенные данные, после сравнения данных df с df_st получается новый DataFrame, как ниже

Ссылка Квартира Адрес Почтовый индекс Проблемы
AS097 NaN 00 Name Road BH1 4HB Нет
AS097 Квартира 1 Название здания 00 Name Road BH1 4HB Нет
AS097 Квартира 2 Название здания 00 Name Rd BH1 4HB Адрес
AS097 Квартира 3 Название здания 00 Name Road BH1 4HB Нет
AS097 Квартира 4 Название здания 00 Name Road BH1 4HB Нет
AS097 Квартира 5 Название здания 00 Name Road BH1 4HX Почтовый индекс
HO056 NaN 23 Street Road XG9 9GX Нет

Где Address появляется как проблема в столбце Issues, так как адреса не совпадают с df_st, так же для PostCode, так как он отличается от df_st

В РЕЗЮМЕ

Все, что я хочу знать, это как сравнивать совпадающие строки по Reference из одного DataFrame с другим и сравнивать другие значения Address и PostCode.

Надеюсь, это имеет смысл.

Вы можете объединить df и df_st по Reference:

df_merged = pd.merge(df, df_st, on="Reference", how="left")

Примечание: how="left" действительно зависит от того, что вы хотите в объединенной таблице. Затем вы можете сравнить значения в объединенных столбцах:

df_merged['Address_df'] == df_merged['Address_df_st']

Ответ или решение

Для эффективного сравнения значений адресов из одного DataFrame с одной строкой из другого DataFrame, вы можете использовать метод объединения в Pandas, который позволяет сопоставить строки на основе определенного критерия, в вашем случае — значения в столбце Reference. После этого осуществить сравнение нужных вам столбцов.

Для начала, давайте определим ваши исходные данные. У вас есть DataFrame, в который хотите внести коррективы, основываясь на данных из DataFrame с основными адресами. Давайте представим, что ваши DataFrame обозначены как df и df_st.

Шаги по выполнению задачи

  1. Объединение DataFrame (Merge):
    Используйте pd.merge() для объединения df и df_st по столбцу Reference. Это создаст новый DataFrame, в котором будут содержаться все строки из df вместе с соответствующими основными адресами из df_st.

    import pandas as pd
    
    df_merged = pd.merge(df, df_st, on='Reference', suffixes=('', '_main'), how='left')

    В данном случае добавляется суффикс _main к столбцам из df_st, чтобы избежать путаницы при сравнении.

  2. Сравнение значений:
    Затем, вам необходимо сравнить значения Address и PostCode в объединённом DataFrame, и создать новый столбец Issues, который будет содержать информацию о том, в каких столбцах есть несоответствия.

    def identify_issues(row):
       issues = []
       if row['Address'] != row['Address_main']:
           issues.append('Address')
       if row['PostCode'] != row['PostCode_main']:
           issues.append('PostCode')
       return ', '.join(issues) if issues else 'None'
    
    df_merged['Issues'] = df_merged.apply(identify_issues, axis=1)
  3. Формирование результирующего DataFrame:
    Полученный DataFrame df_merged будет включать информацию о расхождениях, и будет иметь следующую структуру:

    result = df_merged[['Reference', 'Apartment', 'Address', 'PostCode', 'Issues']]

Пример полного кода

Соберем все в одно целое для наглядности:

import pandas as pd
import numpy as np

# Исходные данные
data = {
    'Reference': ['AS097', 'AS097', 'AS097', 'AS097', 'AS097', 'AS097', 'HO056'],
    'Apartment': [np.nan, 'Flat 1 Building Name', 'Flat 2 Building Name', 
                  'Flat 3 Building Name', 'Flat 4 Building Name', 
                  'Flat 5 Building Name', np.nan],
    'Address': ['00 Name Road', '00 Name Road', '00 Name Rd', 
                '00 Name Road', '00 Name Road', '00 Name Road', '23 Street Road'],
    'PostCode': ['BH1 4HB', 'BH1 4HB', 'BH1 4HB', 'BH1 4HB', 
                 'BH1 4HB', 'BH1 4HX', 'XG9 9GX']
}

data_st = {
    'Reference': ['AS097', 'HO056'],
    'Address': ['00 Name Road', '23 Street Road'],
    'PostCode': ['BH1 4HB', 'XG9 9GX']
}

df = pd.DataFrame(data)
df_st = pd.DataFrame(data_st)

# Объединяем DataFrame
df_merged = pd.merge(df, df_st, on='Reference', suffixes=('', '_main'), how='left')

# Определяем несоответствия
def identify_issues(row):
    issues = []
    if row['Address'] != row['Address_main']:
        issues.append('Address')
    if row['PostCode'] != row['PostCode_main']:
        issues.append('PostCode')
    return ', '.join(issues) if issues else 'None'

df_merged['Issues'] = df_merged.apply(identify_issues, axis=1)

# Получаем результирующий DataFrame
result = df_merged[['Reference', 'Apartment', 'Address', 'PostCode', 'Issues']]

print(result)

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...