Как классифицировать возраст по бинам с шагом 5 лет
Что проверяют
Задача простая, поэтому смотрят на аккуратность: как вы закрываете границы интервалов, что делаете с краями и пропусками, умеете ли обойтись без ручного перечисления бинов. Следом часто просят сделать то же без pandas или объяснить разницу с квантильным разбиением.
Как отвечать
Самый короткий путь в pandas это pd.cut с сеткой, собранной программно:
- сетка:
bins = np.arange(0, 105, 5)даёт границы 0, 5, 10 и так до 100. Руками списки не пишите, в них легко потерять шаг; - границы: по умолчанию
right=True, интервалы вида(0, 5], и тогда пятилетний попадает в одну группу с годовалым, а ноль вообще выпадает (если не задатьinclude_lowest=True). Для возрастных групп нуженright=False, интервалы[0, 5),[5, 10); - подписи: генерируйте из той же сетки, например
f"{b}-{b + 4}"по левым границам. Подписей должно быть на одну меньше, чем границ; - выход за сетку: значения вне диапазона и пропуски получают
NaN. Решите явно: добавить открытый бин доnp.infдля «100+», отфильтровать или считать ошибкой данных; - тип: результат это
Categoricalс упорядоченными категориями, сортировка идёт в правильном порядке. Вgroupbyзадавайтеobservedявно, от него зависит, попадут ли в результат пустые группы.
Без pandas хватает целочисленного деления: age // 5 * 5 даёт левую границу бина, из неё строится подпись. На массивах то же делает np.floor_divide векторно.
Если спросят про альтернативу: pd.qcut режет по квантилям, группы получаются равными по числу людей, но не по ширине. Для модели бинирование возраста часто лишнее, деревья сами найдут пороги, поэтому бины нужны скорее для отчётов и признаков в линейных моделях.
Где спотыкаются
Забывают про right=False. Возраст 30 уходит в группу «25-29», и подписи расходятся с данными.
Пишут границы и подписи двумя независимыми списками. Одна пропущенная граница, и все группы после неё сдвигаются.
Не проверяют результат на граничных значениях 0, 5, 99 и 100 и на отрицательном возрасте из грязных данных.