← Назад к вопросам
В чем разница между 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()
Сравнительная таблица
| Параметр | apply | applymap |
|---|---|---|
| Уровень | столбцы/строки | каждый элемент |
| Параметр axis | есть (0 или 1) | нет |
| Получаемый аргумент | Series | скаляр |
| Типичное использование | агрегация, преобразование Series | преобразование каждого значения |
| Современное имя | apply | map() |
| Производительность | быстрее (есть оптимизации) | медленнее |
Практические примеры
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)и т.д.)