Доли при нулевом знаменателе: np.divide с where и out
В части групп нет посетителей, поэтому конверсия не определена. Попытка завернуть деление в np.where убирает бесконечность из результата, но предупреждение о делении остаётся: обе ветки выражения уже вычислены.
Определить смысл пустого знаменателя
Нулевая конверсия означает, что посетители были, а покупок не было. При нуле посетителей отношение неизвестно. Подмена его нулём создаёт ложную сравнимость групп. Выберите представление заранее: NaN в числовом результате и отдельная маска пригодности.
np.where выбирает между готовыми значениями. Если передать в него выражение purchases / visitors, деление выполняется до выбора. Маска параметра where у самой операции np.divide управляет тем, где операция выполняется.
Инициализировать выходной массив
В позициях, где where ложно, np.divide сохраняет прежнее содержимое out. Поэтому создаём out заранее заполненным NaN. Если полагаться на неинициализированную память, запрещённые позиции не получат осмысленного значения.
Также проверяем диапазон: посетители неотрицательны, покупки неотрицательны и не превосходят посетителей в определении «одна покупка на посетителя». Для количества заказов последнее правило было бы другим.
import numpy as np
buyers = np.array([2., 0., 0.])
visitors = np.array([10., 5., 0.])
assert np.all(visitors >= 0) and np.all((buyers >= 0) & (buyers <= visitors))
valid = visitors > 0
conversion = np.full(visitors.shape, np.nan, dtype=float)
with np.errstate(divide="raise", invalid="raise"):
np.divide(buyers, visitors, out=conversion, where=valid)
print(conversion)
assert np.allclose(conversion[:2], [0.2, 0.0])
assert np.isnan(conversion[2])
assert valid.tolist() == [True, True, False]Первая конверсия 20%, вторая — подтверждённый ноль, третья неизвестна. Режим errstate превращает ошибочное деление в исключение, поэтому запуск дополнительно подтверждает, что запрещённая позиция не вычислялась.
Не потерять неизвестность в следующем шаге
Если затем заменить NaN нулём для графика, смысл снова исчезнет. Передайте маску valid в следующий расчёт или сохраняйте число посетителей рядом с отношением. При сортировке групп неизвестные результаты должны иметь явное место, а не автоматически считаться худшими.
Общую конверсию считают из суммарных покупателей и посетителей. Среднее групповых отношений отвечает на другой вопрос и особенно чувствительно к маленьким группам. Корректная обработка нуля не исправляет неверный способ объединения долей.
Для неизвестных входных чисел добавьте проверку конечности. Условие visitors > 0 само по себе допускает бесконечность. В реальной поставке решите, какие NaN должны оставаться неизвестными, а какие являются ошибкой формата и отправляются в диагностику.
Контрольный набор должен включать обычную долю, известный ноль и нулевой знаменатель. Так формула сохраняет различия, которые нужны читателю отчёта, и не маскирует отсутствие данных техническим значением.
Закрепить на практике
В бесплатном уроке where и clip вы отработаете векторные условия. После него сравните выбор уже вычисленных значений с маской самой операции np.divide из статьи. Откройте бесплатный урок и задачи. Полная последовательность тем — в бесплатном курсе.
Продолжить на практике
- NumPy и pandas: практический тренажёр ↗
Бесплатный тренажёр NumPy и pandas для тех, кто знает основы Python. Научитесь очищать таблицы, объединять данные и собирать отчёты: 31 урок и 124 задачи с кодом и автоматической проверкой.
