[Pandas] apply / map
Pandas apply / map, Pandas Series apply, Pandas Series map, Series.apply, DataFrame.apply elementwise
정의
Series.map(func): 각 원소 에 함수 적용 (또는 dict 매핑)Series.apply(func): 각 원소 에 함수 적용 (map 과 유사)DataFrame.apply(func, axis=): 각 행/열 에 함수 적용DataFrame.map(func)(pandas 2.1+) : 각 셀 에 함수 적용 (구applymap)
Series.map (가장 흔함)
s.map({'A': 1, 'B': 2, 'C': 3}) # dict 매핑
s.map(lambda x: x * 2) # 함수
s.map(some_func)
python
import pandas as pd
s = pd.Series(['cat', 'dog', 'bird', 'cat'])
mapping = {'cat': '고양이', 'dog': '강아지', 'bird': '새'}
print(s.map(mapping).tolist()) 결과
['고양이', '강아지', '새', '고양이']Series.apply
s.apply(lambda x: x ** 2) # 같은 길이의 Series
s.apply(some_func)
map 과 거의 같지만 apply 는 함수에 추가 인자를 줄 수 있다.
s.apply(round, ndigits=2)
DataFrame.apply (행/열 단위)
df.apply(sum, axis=0) # 각 열에 sum (default)
df.apply(sum, axis=1) # 각 행에 sum
# 행 단위 람다
df.apply(lambda r: r['a'] + r['b'], axis=1)
python
import pandas as pd
df = pd.DataFrame({'a': [1,2,3], 'b': [10,20,30]})
print(df.apply(sum)) # 각 열
print('---')
print(df.apply(lambda r: r['a']+r['b'], axis=1)) # 각 행 결과
a 6
b 60
dtype: int64
---
0 11
1 22
2 33
dtype: int64DataFrame.map (셀 단위, pandas 2.1+)
df.map(lambda x: x * 2) # 모든 셀에 x*2
df.map(str) # 모든 셀을 str 으로
구 applymap 의 새 이름.
벡터 연산이 항상 우선
# ❌ apply (행마다 호출, 느림)
df['c'] = df.apply(lambda r: r['a'] + r['b'], axis=1)
# ✓ 벡터 연산 (수십~수백 배 빠름)
df['c'] = df['a'] + df['b']
np.where 패턴
import numpy as np
# ❌ apply
df['cat'] = df['age'].apply(lambda x: 'adult' if x >= 18 else 'minor')
# ✓ np.where
df['cat'] = np.where(df['age'] >= 18, 'adult', 'minor')
# 더 많은 분기: np.select
conditions = [df['age'] < 13, df['age'] < 20, df['age'] < 65]
choices = ['child', 'teen', 'adult']
df['cat'] = np.select(conditions, choices, default='senior')
map vs apply 차이
| 메서드 | 대상 | dict 매핑 | 추가 인자 |
|---|---|---|---|
Series.map | 원소 | ✓ | ✗ |
Series.apply | 원소 | ✗ | ✓ |
DataFrame.apply | 행/열 | ✗ | ✓ |
DataFrame.map | 셀 | ✗ | ✓ |
함정
1. apply 의 속도
# 1000 행 × 10 컬럼 → 10000 호출
df.apply(complex_function, axis=1) # 수초
df.map(complex_function) # 더 느림 (셀마다)
# 벡터화 가능하면 그게 훨씬 빠름
2. axis 0 vs 1 의 의미
df.apply(fn, axis=0) # 각 열에 fn (default)
df.apply(fn, axis=1) # 각 행에 fn
axis=0 은 “행을 collapse” → 결과는 컬럼별. axis=1 은 “열을 collapse” → 결과는 행별. 헷갈리기 쉽다.
3. 결과 타입 추론
result = df.apply(some_func, axis=1)
# 함수 반환이 scalar 면 Series, dict/Series 면 DataFrame
복잡한 함수의 결과 타입은 일정하지 않을 수 있음.
참고
이 글의 용어 (3개)
- [Pandas] DataFramepandas
- 정의 은 2차원 레이블 테이블. 각 열이 , 모든 열이 같은 (행 라벨) 를 공유. SQL 테이블 / Excel 시트 / R data.frame 의 Python 대응체. 생성 <…
- [Pandas] Seriespandas
- 정의 는 1차원 레이블 배열. NumPy + 의 결합. 의 한 열이 곧 Series. 핵심 속성 | 속성 | 의미 | |:---|:---| | | numpy array | | |…
- [Pandas] transform / applypandas
- 정의 | 메서드 | 입력 | 출력 | 용도 | |:---|:---|:---|:---| | | 그룹 | 같은 shape | 정규화, 보충 | | | 그룹 | 임의 shape | 가…
💬 댓글