Замена значений: replace и map

Замена значений: replace и map Pandas

Привет! Ты уже знаешь, как добавлять и удалять колонки. Но что делать, если внутри колонки есть опечатки, лишние пробелы или значения, которые нужно перекодировать? Например, в колонке «Город» у тебя написано «Москва», «Москва» и «Мск» — а должны быть все одинаковые. Или нужно преобразовать числа в категории: «1» → «Низкий», «2» → «Средний», «3» → «Высокий».

В этой статье мы разберём два мощных инструмента Pandas:

  • replace() — для замены конкретных значений в любой части DataFrame
  • map() — для преобразования значений по словарю или функции

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный Pandas (pip install pandas)
  • Базовое понимание DataFrame и колонок
  • Знание словарей и лямбда-функций

Совет: replace() и map() — два способа решить похожие задачи. Важно понимать, когда какой лучше использовать.

Основная часть

Подготовка данных

import pandas as pd
import numpy as np

# Создаём данные с проблемами
data = {
    'Имя': ['Анна', 'Иван', 'Мария', 'Пётр', 'Ольга', 'Сергей'],
    'Город': ['Москва', 'СПб', 'Казань', 'МСК', 'Екатеринбург', 'Москва'],
    'Оценка': ['Хорошо', 'Отлично', 'Удовлетворительно', 'Хорошо', 'Отлично', 'Плохо'],
    'Баллы': [85, 92, 70, 88, 95, 55]
}

df = pd.DataFrame(data)
print("Исходные данные:")
print(df)

Результат:

     Имя          Город              Оценка  Баллы
0   Анна         Москва             Хорошо     85
1   Иван            СПб            Отлично     92
2  Мария         Казань  Удовлетворительно     70
3   Пётр            МСК             Хорошо     88
4  Ольга  Екатеринбург            Отлично     95
5 Сергей         Москва              Плохо     55

Совет: Обрати внимание: в колонке «Город» есть три разных варианта написания Москвы. Это частая проблема в реальных данных.

replace() — замена значений в колонке

replace() заменяет одни значения на другие. Это самый прямой способ исправить опечатки.

Замена одного значения

# Заменяем "МСК" на "Москва"
df['Город'] = df['Город'].replace('МСК', 'Москва')
print(df)

Результат:

     Имя          Город              Оценка  Баллы
0   Анна         Москва             Хорошо     85
1   Иван            СПб            Отлично     92
2  Мария         Казань  Удовлетворительно     70
3   Пётр         Москва             Хорошо     88
4  Ольга  Екатеринбург            Отлично     95
5 Сергей         Москва              Плохо     55

Замена нескольких значений с помощью словаря

# Создаём словарь: что на что менять
city_map = {
    'МСК': 'Москва',
    'СПб': 'Санкт-Петербург'
}

df['Город'] = df['Город'].replace(city_map)
print(df)

Результат:

     Имя              Город              Оценка  Баллы
0   Анна             Москва             Хорошо     85
1   Иван  Санкт-Петербург            Отлично     92
2  Мария             Казань  Удовлетворительно     70
3   Пётр             Москва             Хорошо     88
4  Ольга      Екатеринбург            Отлично     95
5 Сергей             Москва              Плохо     55

Замена во всём DataFrame

# Заменяем во всём DataFrame
df = df.replace('Отлично', '5')
df = df.replace('Хорошо', '4')
df = df.replace('Удовлетворительно', '3')
df = df.replace('Плохо', '2')
print(df)

Совет: replace() работает и с целым DataFrame, не только с одной колонкой. Это удобно, если нужно заменить какое-то значение во всех колонках.

Использование регулярных выражений в replace()

# Удаляем лишние пробелы в начале и конце
df['Город'] = df['Город'].replace(r'^\s+|\s+$', '', regex=True)

# Заменяем все варианты написания "Москва"
df['Город'] = df['Город'].replace(r'Москва|МСК|Мск', 'Москва', regex=True)

Замена с ограничением замены

# Заменяем только первое вхождение "Москва" в колонке
df['Город'] = df['Город'].replace('Москва', 'MSK', limit=1)

Совет: limit контролирует, сколько замен сделать. Это полезно, когда нужно заменить только часть данных.

map() — преобразование по словарю или функции

map() работает только с одной колонкой (Series) и применяет преобразование к каждому элементу. Он принимает на вход либо словарь, либо функцию.

map() со словарём

# Создаём словарь для перевода оценок в цифры
grade_to_num = {
    'Отлично': 5,
    'Хорошо': 4,
    'Удовлетворительно': 3,
    'Плохо': 2
}

df['Оценка_число'] = df['Оценка'].map(grade_to_num)
print(df)

Результат:

     Имя              Город              Оценка  Баллы  Оценка_число
0   Анна             Москва             Хорошо     85             4
1   Иван  Санкт-Петербург            Отлично     92             5
2  Мария             Казань  Удовлетворительно     70             3
3   Пётр             Москва             Хорошо     88             4
4  Ольга      Екатеринбург            Отлично     95             5
5 Сергей             Москва              Плохо     55             2

map() с лямбда-функцией

# Переводим баллы в категории
df['Категория'] = df['Баллы'].map(
    lambda x: 'Высокий' if x > 85 else 'Средний' if x > 70 else 'Низкий'
)
print(df[['Имя', 'Баллы', 'Категория']])

Результат:

     Имя  Баллы  Категория
0   Анна     85     Средний
1   Иван     92    Высокий
2  Мария     70      Низкий
3   Пётр     88    Высокий
4  Ольга     95    Высокий
5 Сергей     55      Низкий

map() с функцией

def format_city(city):
    return city.upper()

df['Город_верхний'] = df['Город'].map(format_city)
print(df[['Город', 'Город_верхний']])

Результат:

              Город  Город_верхний
0             Москва         МОСКВА
1  Санкт-Петербург  САНКТ-ПЕТЕРБУРГ
2             Казань          КАЗАНЬ
3             Москва         МОСКВА
4      Екатеринбург   ЕКАТЕРИНБУРГ
5             Москва         МОСКВА

Совет: map() часто используют для категоризации числовых данных (как в примере с баллами) или для перевода значений из одного формата в другой.

Сравнение replace() и map()

Характеристикаreplace()map()
Работает сDataFrame или SeriesSeries (одна колонка)
Замена по словарюДАДА
Замена по функцииНЕТДА
Работает с регулярными выражениямиДАНЕТ
Может заменить во всём DataFrameДАНЕТ
Обработка NaNДА (можно заменить)НЕТ (NaN остаётся NaN)

Совет: Используй replace() для замены конкретных значений (особенно с regex). Используй map() для преобразований с помощью функций (особенно для категоризации).

Практический пример: очистка данных

import pandas as pd
import numpy as np

# Грязные данные
data = {
    'Имя': ['Анна', 'Иван', 'Мария', 'Пётр', 'Ольга', 'Сергей'],
    'Город': ['Москва', 'Спб', 'Казань', 'Moscow', 'Екатеринбург', 'Москва '],
    'Статус': ['active', 'inactive', 'active', 'Active', 'inactive', 'inactive'],
    'Зарплата': [50000, 60000, 45000, 70000, 55000, 80000]
}

df = pd.DataFrame(data)
print("Исходные данные:")
print(df)

print("\n=== Очистка данных ===")

# 1. Исправляем опечатки в городах
city_fix = {
    'Спб': 'Санкт-Петербург',
    'Moscow': 'Москва',
    'Москва ': 'Москва'
}
df['Город'] = df['Город'].replace(city_fix)

# 2. Приводим статус к нижнему регистру
df['Статус'] = df['Статус'].map(lambda x: x.lower())

# 3. Заменяем статус на человекочитаемый
status_map = {
    'active': 'Активен',
    'inactive': 'Неактивен'
}
df['Статус_рус'] = df['Статус'].map(status_map)

# 4. Добавляем категорию по зарплате
def salary_category(salary):
    if salary > 70000:
        return 'Высокая'
    elif salary > 50000:
        return 'Средняя'
    else:
        return 'Низкая'

df['Категория_зарплаты'] = df['Зарплата'].map(salary_category)

print(df)

Результат:

     Имя              Город    Статус  Зарплата Статус_рус Категория_зарплаты
0   Анна             Москва    active     50000   Активен           Низкая
1   Иван  Санкт-Петербург  inactive     60000  Неактивен          Средняя
2  Мария             Казань    active     45000   Активен           Низкая
3   Пётр             Москва    active     70000   Активен          Средняя
4  Ольга      Екатеринбург  inactive     55000  Неактивен          Средняя
5 Сергей             Москва  inactive     80000  Неактивен          Высокая

map() для создания новых колонок

map() часто используют, чтобы создать новую колонку на основе существующей:

# Создаём колонку с длиной имени
df['Длина_имени'] = df['Имя'].map(len)

# Создаём колонку с первой буквой имени
df['Первая_буква'] = df['Имя'].map(lambda x: x[0])

print(df[['Имя', 'Длина_имени', 'Первая_буква']])

replace() с NaN

replace() может заменять и пропуски:

# Создаём данные с пропусками
df_with_nan = pd.DataFrame({
    'Город': ['Москва', np.nan, 'Казань', 'Москва'],
    'Оценка': [5, 4, np.nan, 5]
})

# Заменяем NaN на 'Неизвестно'
df_with_nan = df_with_nan.replace(np.nan, 'Неизвестно')
print(df_with_nan)

map() vs applymap()

map() работает с одной колонкой. Если нужно применить функцию ко всему DataFrame, используй applymap():

# Применяем функцию ко всем элементам DataFrame
df_strings = pd.DataFrame({
    'A': ['hello', 'world'],
    'B': ['python', 'pandas']
})

# Переводим все строки в верхний регистр
df_upper = df_strings.applymap(str.upper)
print(df_upper)

Совет: applymap() полезен, когда нужно выполнить одну и ту же операцию над всеми ячейками DataFrame (например, очистить пробелы).

Инструменты замены в Pandas

МетодЧто делаетПрименение
replace()Заменяет конкретные значенияИсправление опечаток, замена значений
map()Применяет словарь или функцию к колонкеКатегоризация, преобразование
applymap()Применяет функцию ко всему DataFrameОбщая очистка данных
str.replace()Заменяет подстроки в строкахРабота с текстом

Задачи для закрепления

Задача 1. Замени все вхождения «Москва» на «MSK» в колонке Город.

Задача 2. Создай словарь для замены оценок: {'Отлично': 5, 'Хорошо': 4, 'Удовлетворительно': 3, 'Плохо': 2} и примени его с помощью replace().

Задача 3. С помощью map() добавь колонку Оценка_текст, которая переводит баллы в категории: > 90 → 'A'> 80 → 'B'> 70 → 'C'<= 70 → 'D'.

Задача 4. С помощью replace() удали все пробелы в начале и конце строк в колонке Имя (используй регулярные выражения).

Задача 5. В чём разница между replace() и map()?

Ответы:

Задача 1.

df['Город'] = df['Город'].replace('Москва', 'MSK')

Задача 2.

grade_map = {
    'Отлично': 5,
    'Хорошо': 4,
    'Удовлетворительно': 3,
    'Плохо': 2
}
df['Оценка_число'] = df['Оценка'].replace(grade_map)

Задача 3.

def grade_category(score):
    if score > 90:
        return 'A'
    elif score > 80:
        return 'B'
    elif score > 70:
        return 'C'
    else:
        return 'D'

df['Оценка_текст'] = df['Баллы'].map(grade_category)

Задача 4.

df['Имя'] = df['Имя'].replace(r'^\s+|\s+$', '', regex=True)

Задача 5.

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

Нюансы и подводные камни

replace() не изменяет исходный DataFrame по умолчанию

# Не изменится
df.replace('Москва', 'MSK')

# Правильно (сохраняем результат)
df['Город'] = df['Город'].replace('Москва', 'MSK')

map() не обрабатывает NaN

map() оставляет NaN как есть:

# В колонке с NaN map() их не меняет
df['Кол'] = df['Кол'].map(lambda x: x * 2)  # NaN остаётся NaN

regex в replace()

Не забудь включить regex=True, если используешь регулярные выражения.

Частые ошибки и как их избежать

Ошибка 1: Забыл присвоить результат replace()

# Ничего не изменится
df.replace('Москва', 'MSK')

# Присваиваем результат
df['Город'] = df['Город'].replace('Москва', 'MSK')

Ошибка 2: Путаница между replace() и map()

# replace не может принимать функцию
df['Баллы'].replace(lambda x: x * 2)

# map() может принимать функцию
df['Баллы'].map(lambda x: x * 2)

Ошибка 3: map() с неправильным словарём

Если значения нет в словаре, map() вернёт NaN. Для замены нескольких значений лучше использовать replace().

Шпаргалка

Что нужноКак пишется
Заменить одно значениеdf['Кол'] = df['Кол'].replace('старое', 'новое')
Заменить несколько значений (словарь)df['Кол'] = df['Кол'].replace({'старое1': 'новое1', 'старое2': 'новое2'})
Заменить во всём DataFramedf = df.replace('старое', 'новое')
Заменить с regexdf['Кол'] = df['Кол'].replace(r'шаблон', 'замена', regex=True)
Преобразовать с помощью словаряdf['Кол'] = df['Кол'].map(словарь)
Преобразовать с помощью функцииdf['Кол'] = df['Кол'].map(lambda x: x * 2)
Применить ко всему DataFramedf = df.applymap(lambda x: x.strip())
Заменить в строкахdf['Кол'] = df['Кол'].str.replace('подстрока', 'новая')

Заключение

Сегодня мы научились:

  • Заменять значения с помощью replace()
  • Преобразовывать данные с помощью map()
  • Использовать словари и функции для преобразований
  • Очищать данные от опечаток и пробелов
  • Категоризировать числовые данные

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×