Задача курса

pandas merge и дубли ключей: диагностика зерна данных

Курс «NumPy и pandas: практический тренажёр» · урок «Итоговый практикум — часть 2: агрегация, соединение и финальная схема»

Условие

Диагностика зерна: метрика до обогащения vs после one-to-many join

Вы реализуете функцию diagnose_grain, которая принимает таблицу фактов и таблицу-измерение с возможными дублями по ключу, вычисляет суммарную метрику до join (на правильном зерне) и после наивного left join (где дубли в измерении умножают строки), а затем возвращает компактный диагностический словарь.

Что уже дано

Проверяющая система вызывает diagnose_grain(facts, dim, key_col, metric_col), передавая четыре аргумента:

  • facts — pd.DataFrame, таблица фактов. Не содержит дублей по key_col.
  • dim — pd.DataFrame, таблица-измерение. Может содержать дубли по key_col (именно это создаёт проблему зерна).
  • key_col — str, имя столбца-ключа, по которому выполняется join.
  • metric_col — str, имя числового столбца в facts, по которому считается сумма.

Никаких файлов, глобальных переменных и состояния из других уроков нет.

Что нужно сделать

Реализуйте функцию diagnose_grain(facts, dim, key_col, metric_col), которая выполняет ровно три шага.

Шаг 1. Метрика на правильном зерне.
Вычислите суммарное значение metric_col по всей таблице facts до любого join:

true_total = float(facts[metric_col].sum())

Шаг 2. Наивный left join и метрика после.
Выполните pd.merge(facts, dim, on=key_col, how='left') без validate (намеренно разрешая размножение строк). Вычислите сумму metric_col в результате:

joined = pd.merge(facts, dim, on=key_col, how='left')
naive_total = float(joined[metric_col].sum())

Шаг 3. Диагностика.
Вычислите:

  • row_inflation — во сколько раз выросло число строк: round(joined.shape[0] / facts.shape[0], 4)
  • metric_inflation — во сколько раз выросла сумма метрики: round(naive_total / true_total, 4) (если true_total == 0, верните None)
  • is_safe — True, если joined.shape[0] == facts.shape[0] (дублей не было, зерно не изменилось)

Верните словарь:

{
 'true_total': true_total,
 'naive_total': naive_total,
 'row_inflation': row_inflation,
 'metric_inflation': metric_inflation,
 'is_safe': is_safe
}

Ввод и вывод

stdin не используется. Печатать через print в stdout ничего не нужно.

Проверяющая система вызывает diagnose_grain(facts, dim, key_col, metric_col) и проверяет возвращаемый словарь. Функция принимает четыре аргумента:

  • facts — непустой pd.DataFrame (минимум одна строка);
  • dim — pd.DataFrame;
  • key_col — str;
  • metric_col — str.

Функция должна вернуть словарь с ключами 'true_total' (float), 'naive_total' (float), 'row_inflation' (float), 'metric_inflation' (float или None), 'is_safe' (bool).

Пример использования

import pandas as pd

facts = pd.DataFrame({
 'store_id': [1, 2, 3],
 'revenue': [100.0, 200.0, 300.0],
})
dim = pd.DataFrame({
 'store_id': [1, 2, 2, 3],
 'city': ['Москва', 'Казань', 'Казань2', 'Уфа'],
})
result = diagnose_grain(facts, dim, key_col='store_id', metric_col='revenue')
print(result['true_total'])
print(result['naive_total'])
print(result['row_inflation'])
print(result['is_safe'])

Результат:

600.0
800.0
1.3333
False

Попробуйте решить

РешениеPython
Без регистрации · результат не сохраняется