pandas merge сопоставил пустые ключи: как защитить отчёт от ложных совпадений
К выгрузке заказов добавили сегмент клиента. После объединения часть анонимных покупок получила сегмент «корпоративный», а сумма отчёта выросла. В справочнике оказалась строка с пустым идентификатором. Аналитик ожидал поведения SQL: неизвестный ключ ни с чем не совпадает. Но pandas merge сопоставляет пустые ключи между собой.
Такое соединение особенно опасно в отчётах, где неизвестные значения появляются с обеих сторон. Если слева три пустых ключа, а справа два, совпадения дадут шесть строк. Даже без размножения строк можно получить ошибочную классификацию продаж. Поэтому проверка общей суммы необходима, но её недостаточно.
Сначала определить допустимые ключи
Заказ без известного клиента остаётся настоящим заказом. Его нельзя выбрасывать только потому, что справочник неполный. А вот строка справочника без ключа не описывает конкретного клиента и не должна участвовать в сопоставлении.
Для обогащения заказов сегментом оставим все заказы, очистим правую сторону от пропущенных ключей и потребуем её уникальности. Это выразит правило: много заказов могут принадлежать одному клиенту, но один идентификатор справочника не должен давать несколько сегментов.
Пример с проверками результата
import pandas as pd
orders = pd.DataFrame({
'order_id': [10, 11, 12],
'client_id': pd.array([1, None, None], dtype='Int64'),
'amount': [100, 200, 300],
})
clients = pd.DataFrame({
'client_id': pd.array([1, None], dtype='Int64'),
'segment': ['retail', 'corporate'],
})
known_clients = clients.dropna(subset=['client_id'])
result = orders.merge(
known_clients, on='client_id', how='left',
validate='many_to_one', indicator=True,
)
print(result[['order_id', 'segment', '_merge']].to_string(index=False))
assert len(result) == len(orders)
assert result['amount'].sum() == orders['amount'].sum()
assert result.loc[result['client_id'].isna(), 'segment'].isna().all()У заказа 10 появится retail, а у 11 и 12 сегмент останется пропущенным. В колонке _merge первый заказ получит both, остальные — left_only. Все 600 денежных единиц сохранятся в отчёте.
Здесь validate='many_to_one' проверяет уникальность ключей справа. Если в справочнике появятся два сегмента для клиента 1, merge завершится ошибкой. Это полезнее незаметного удвоения выручки. Удалять произвольный дубль перед объединением стоит только после решения, какая версия справочника считается действующей.
Различать причины отсутствующего сегмента
Значение left_only объединяет две разные ситуации: у заказа нет идентификатора либо идентификатор есть, но его не нашли в справочнике. Для работы с источником разделите их. В первом случае проверяют сбор данных о клиентах. Во втором — полноту и свежесть справочника.
Не заполняйте оба случая словом «прочие» до этой проверки. В графике такая группа выглядит безобидно, хотя внутри может расти доля потерянных ключей. Сначала посчитайте количество и сумму заказов по каждой причине, затем решите, какую подпись показать бизнесу.
Для составного ключа правило применяется ко всем обязательным полям. Если совпадение разрешено только при известных company_id и client_id, убирайте из правой таблицы строки с пропуском любого из них. При этом пустая строка и NULL — разные значения. Пробелы и текстовые маркеры вроде «неизвестно» нужно привести к согласованному виду до merge.
Как встроить это в повторяемый отчёт
Сохраните три контроля рядом с расчётом: число строк до и после, сумму денежного поля и долю заказов без найденного клиента. На новой выгрузке они покажут изменение раньше, чем оно окажется на дашборде. Отдельный пример с пустым ключом полезно оставить среди контрольных входов.
Разберите задачи на groupby и merge, чтобы закрепить выбор типа соединения и проверку итоговой таблицы.
Следующий шаг — связать проверенные данные с вопросом бизнеса. В курсе «Практическая аналитика данных» вы проверяете пропуски, дубли и последствия объединений, считаете продажи и клиентские показатели, а затем собираете дашборд и объясняете выводы. Откройте программу и выберите маршрут расчётов на pandas.
Продолжить на практике
- Практическая аналитика данных ↗
Превратите знания SQL или Python в аналитическую работу: проверяйте данные, считайте бизнес-метрики, стройте дашборды и объясняйте выводы на трёх прикладных кейсах.
