apply, map и replace часто решают похожие задачи, поэтому начинающие аналитики используют их почти наугад. Отсюда появляются и медленные ноутбуки, и лишние ошибки.

Короткая версия:

  • map() — для преобразования одной Series
  • replace() — для замены конкретных значений
  • apply() — более универсальный, но часто избыточный

map — когда работаем с одним столбцом

map() обычно применяют к Series.

Например, заменить коды городов на названия:

df["city_name"] = df["city_code"].map({
    1: "Москва",
    2: "СПб",
    3: "Казань"
})

Или применить функцию:

df["name_len"] = df["name"].map(len)

Подходит для:

  • словарных замен
  • простых преобразований в одном столбце

replace — когда нужно заменить конкретные значения

replace() хорош, когда ты хочешь заменить старые значения на новые без “логики вычисления”.

df["status"] = df["status"].replace({
    "new": "новый",
    "done": "завершен"
})

Или сразу по всему DataFrame:

df = df.replace({"N/A": None, "-": None})

Подходит для:

  • очистки мусорных значений
  • массовой замены по словарю
  • замены по всей таблице

apply — более общий инструмент

apply() гибче, но именно из-за этого его часто используют там, где можно проще.

Пример для одного столбца:

df["price_with_tax"] = df["price"].apply(lambda x: x * 1.2)

Пример по строкам:

df["full_name"] = df.apply(
    lambda row: row["first_name"] + " " + row["last_name"],
    axis=1
)

Подходит для:

  • более сложной логики
  • функций по строкам или столбцам
  • случаев, когда map() уже не хватает

Когда что использовать

Если есть один столбец и простая замена

Чаще всего map() или replace().

Если нужно заменить конкретные значения

replace().

Если нужна произвольная функция

apply().

Частая ошибка №1: использовать apply вместо map

Например:

df["city_name"] = df["city_code"].apply(lambda x: city_dict[x])

Хотя проще и понятнее:

df["city_name"] = df["city_code"].map(city_dict)

Здесь map() читается лучше.

Частая ошибка №2: использовать apply там, где хватит векторной операции

Например:

df["double_price"] = df["price"].apply(lambda x: x * 2)

Лучше так:

df["double_price"] = df["price"] * 2

В pandas очень часто самое хорошее решение — не apply(), а обычная векторная операция.

Частая ошибка №3: не понимать, что map работает только для Series

map() не применяется к DataFrame целиком.

Если задача касается всей таблицы, смотри на:

  • replace()
  • apply()
  • векторные операции

Итог

Шпаргалка простая:

  • один столбец + словарь / простая функция -> map()
  • замена конкретных значений -> replace()
  • более сложная логика -> apply()

А еще лучше запомнить более практичное правило:

  • сначала подумай, нельзя ли решить задачу обычной векторной операцией
  • если нет, смотри на map() или replace()
  • apply() оставляй на случаи, где он действительно нужен