← Назад к вопросам

В чем разница между apply и applymap в Pandas?

1.0 Junior🔥 131 комментариев
#Pandas и обработка данных

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между apply и applymap в Pandas

Это две разные функции с разными целями. Часто их путают, но они работают на разных уровнях.

apply: применение функции к строкам/столбцам

apply применяет функцию к целым строкам или столбцам DataFrame или Series.

import pandas as pd
import numpy as np

# Создадим DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3, 4],
    'B': [5, 6, 7, 8],
    'C': [9, 10, 11, 12]
})

print(df)
#    A  B   C
# 0  1  5   9
# 1  2  6  10
# 2  3  7  11
# 3  4  8  12

# apply по столбцам (axis=0, default)
df.apply(np.sum)  # сумма каждого столбца
# A    10
# B    26
# C    42
# dtype: int64

# apply по строкам (axis=1)
df.apply(lambda row: row.sum(), axis=1)  # сумма каждой строки
# 0    15
# 1    18
# 2    21
# 3    24
# dtype: int64

# Пример: вычислить среднее каждого столбца
df.apply(np.mean)
# A    2.5
# B    6.5
# C   10.5

Ключевые особенности apply:

  • Работает со Series или целыми столбцами/строками
  • Принимает параметр axis: 0 (столбцы), 1 (строки)
  • Функция получает весь столбец/строку как Series
  • Может вернуть Series или скаляр
# Пример: кастомная функция для apply
def custom_function(series):
    """Функция получает весь столбец"""
    return series.max() - series.min()  # размах значений

df.apply(custom_function)
# A    3
# B    3
# C    3
# dtype: int64

applymap: применение функции к каждому элементу

applymap (с Pandas 2.1.0 переименована в map) применяет функцию к каждому отдельному элементу DataFrame.

# applymap применяет функцию к каждой ячейке
df.applymap(lambda x: x ** 2)  # возведение в квадрат каждого элемента
#     A   B    C
# 0   1  25   81
# 1   4  36  100
# 2   9  49  121
# 3  16  64  144

# Пример: округление
df.applymap(lambda x: round(x, 2))

# Пример: преобразование в строки
df.applymap(str)
#    A  B   C
# 0  1  5   9
# 1  2  6  10
# 2  3  7  11
# 3  4  8  12
# (но все строки теперь)

Ключевые особенности applymap:

  • Работает с каждой отдельной ячейкой
  • Не имеет параметра axis (работает на всех элементах)
  • Функция получает скалярное значение
  • Вернёт скаляр для каждой ячейки
  • С Pandas 2.1.0+ переименована в map()

Сравнительная таблица

Параметрapplyapplymap
Уровеньстолбцы/строкикаждый элемент
Параметр axisесть (0 или 1)нет
Получаемый аргументSeriesскаляр
Типичное использованиеагрегация, преобразование Seriesпреобразование каждого значения
Современное имяapplymap()
Производительностьбыстрее (есть оптимизации)медленнее

Практические примеры

df = pd.DataFrame({
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Salary': [50000, 60000, 75000],
    'Age': [28, 35, 42]
})

# APPLY: вычислить среднее зарплаты по каждому столбцу
print(df[['Salary', 'Age']].apply(np.mean))
# Salary    61666.666667
# Age          35.000000

# APPLY: преобразовать все строки в список (axis=1)
df.apply(list, axis=1)
# 0    [Alice, 50000, 28]
# 1      [Bob, 60000, 35]
# 2    [Charlie, 75000, 42]

# APPLYMAP: удалить все пробелы из каждой ячейки
df_with_spaces = df.copy()
df_with_spaces['Name'] = df_with_spaces['Name'].apply(lambda x: '  ' + x + '  ')
df_with_spaces.applymap(lambda x: str(x).strip() if isinstance(x, str) else x)

# APPLYMAP: умножить все числа на 1.1
df[['Salary', 'Age']].applymap(lambda x: x * 1.1)

Реальный пример: data cleaning

# Датасет с грязными данными
df = pd.DataFrame({
    'Amount': [' 100 ', '  200', '300  '],
    'Rate': [' 0.1 ', '0.2', ' 0.3 ']
})

print(df)
#  Amount  Rate
# 0   100    0.1
# 1   200    0.2
# 2   300    0.3

# Очистить пробелы и конвертировать в float
df_clean = df.applymap(lambda x: float(str(x).strip()))
print(df_clean)
#   Amount  Rate
# 0   100.0  0.1
# 1   200.0  0.2
# 2   300.0  0.3

Реальный пример: feature engineering

df = pd.DataFrame({
    'income': [50000, 60000, 75000],
    'expenses': [40000, 45000, 50000]
})

# apply: вычислить savings rate для каждой строки
df['savings_rate'] = df[['income', 'expenses']].apply(
    lambda row: (row['income'] - row['expenses']) / row['income'],
    axis=1
)

print(df)
#   income  expenses  savings_rate
# 0  50000     40000      0.200000
# 1  60000     45000      0.250000
# 2  75000     50000      0.333333

Производительность

import time

df_large = pd.DataFrame(np.random.rand(1000, 100))

# apply
start = time.time()
df_large.apply(np.sqrt)
print(f"apply: {time.time() - start:.4f} сек")

# applymap
start = time.time()
df_large.applymap(np.sqrt)
print(f"applymap: {time.time() - start:.4f} сек")

# Результат:
# apply: 0.0050 сек
# applymap: 0.0450 сек  ← медленнее в 9 раз!

applymap медленнее, поэтому используй vectorized операции NumPy/Pandas где возможно!

Современный Pandas (2.1.0+)

# applymap переименована в map()
df.map(lambda x: x ** 2)  # новый способ
df.applymap(lambda x: x ** 2)  # старый способ (deprecated)

Вывод

  • apply — для агрегации/трансформации строк или столбцов (быстро)
  • applymap/map — для преобразования каждого элемента (медленно)
  • apply с axis=0/1 — обычно быстрее
  • applymap — когда нет другого выхода
  • Лучший выбор — vectorized операции NumPy/Pandas (df.values ** 2, df.mul(2) и т.д.)