КПКейсПрактика
Все материалы
Продуктовая аналитикагайдсредний

Pandas apply и векторизация: как писать быстрее и понятнее

Когда использовать apply, почему векторные операции быстрее и как переписать медленный построчный расчёт в pandas.

КПКейсПрактика7 августа 2026 г.11 мин
Два аналитика заменяют медленную цепочку построчных операций pandas на быстрый векторный расчёт.

В pandas почти всегда можно написать расчёт через `apply`, и это удобно для первого прототипа. Но функция, вызываемая для каждой строки, часто становится медленным местом и скрывает типы данных. Векторизация переносит операцию на целый столбец и обычно делает код короче, быстрее и легче для проверки.

Коротко

`apply(axis=1)` — хороший инструмент для сложного правила, которое трудно выразить иначе. Для арифметики, строковых методов, условий и дат сначала ищи операцию над всей Series. `map` и `replace` удобны для словаря значений, `np.select` — для нескольких условий.

  • Начни с векторной операции и переходи к apply только при необходимости.
  • Не используй `axis=1`, если условие зависит от одной колонки.
  • Замеряй время на репрезентативном объёме данных.
  • После переписывания сравни результат старой и новой версии на выборке.

Простая арифметика не требует apply

Построчный код выглядит привычно, но pandas уже умеет выполнять операцию над всей колонкой. Векторная версия лучше показывает формулу и не создаёт Python-вызов на каждую строку.

pythonПереписать расчёт скидки
# Медленнее и сложнее читать на больших таблицах
orders['net_revenue'] = orders.apply(
    lambda row: row['revenue'] - row['discount'], axis=1
)

# Векторная версия
orders['net_revenue'] = orders['revenue'] - orders['discount']

Условия: np.select вместо вложенных if

Когда сегмент зависит от нескольких условий, `np.select` делает порядок правил явным. Условия проверяются сверху вниз, поэтому сначала ставь более специфичное правило. Значение `default` обязательно: иначе неизвестный случай легко потеряется.

pythonСегментировать заказ по сумме
import numpy as np

conditions = [
    orders['revenue'].ge(5000),
    orders['revenue'].ge(1500),
    orders['revenue'].ge(0),
]
choices = ['high', 'medium', 'low']
orders['order_segment'] = np.select(conditions, choices, default='invalid')

map и str работают над колонкой

Словарь каналов, нормализация регистра и поиск части строки не требуют построчной функции. Такие операции проще покрыть тестами и легче заметить, если неизвестное значение превратилось в пропуск.

pythonНормализовать категории
channel_names = {'paid_social': 'paid', 'paid_search': 'paid'}
orders['channel_group'] = orders['channel'].map(channel_names)
orders['channel_group'] = orders['channel_group'].fillna('other')

orders['campaign'] = (
    orders['campaign'].astype('string').str.strip().str.lower()
)

Когда apply оправдан

Если правило использует несколько значений строки, вызывает сложную доменную функцию или строит небольшой текстовый объект, `apply` может быть самым понятным решением. Не нужно переписывать всё ради скорости. Сначала измерь узкое место и зафиксируй ожидаемый результат.

Выбор операции для типовой задачи
ЗадачаПервый кандидат
арифметика колоноквекторные операции
словарь категорийmap / replace
несколько независимых условийnp.select
дата и строкаdt / str accessor
правило использует всю строкуapply(axis=1), затем замерить
Быстрее — не всегда лучше

Векторный код, который никто не понимает, может быть хуже медленного, но проверяемого правила. Сначала сохраняй бизнес-смысл, затем оптимизируй подтверждённое узкое место.

Продолжить чтение
Вся библиотека