[Pandas] iterrows / itertuples
Pandas iterrows, Pandas itertuples, pandas 행 순회
정의
iterrows(): (index, Series) 순회itertuples(): NamedTuple 순회 (빠름, 권장)items(): (column_name, Series) 순회
기본
for idx, row in df.iterrows():
print(idx, row['name'], row['age'])
for row in df.itertuples():
print(row.Index, row.name, row.age)
성능 비교 (강한 권고: 가능하면 벡터 연산)
python
import pandas as pd
import time
df = pd.DataFrame({'a': range(100_000), 'b': range(100_000)})
t = time.time(); total = 0
for _, r in df.iterrows(): total += r['a'] + r['b']
print(f'iterrows: {time.time()-t:.2f}s')
t = time.time(); total = 0
for r in df.itertuples(): total += r.a + r.b
print(f'itertuples: {time.time()-t:.2f}s')
t = time.time()
total = (df['a'] + df['b']).sum()
print(f'vectorized: {time.time()-t:.4f}s') 결과
iterrows: 3.85s
itertuples: 0.18s
vectorized: 0.0009sitertuples 가 iterrows 보다 ~20 배 빠르고, 벡터 연산은 다시 그 200 배 빠르다.
IMPORTANT
거의 모든 경우 iterrows / itertuples 를 피하라. 벡터 연산 / apply / np.where / groupby 로 같은 결과를 만들 수 있는지 먼저 검토. 정 필요하면 itertuples.
itertuples 옵션
df.itertuples() # NamedTuple with Index
df.itertuples(index=False) # Index 제거
df.itertuples(name='Row') # NamedTuple 이름 지정
iterrows 의 함정
1. dtype 손실
iterrows 는 각 행을 Series 로 반환. 같은 컬럼이 다른 dtype 이면 모두 object 로 강등.
for _, r in df.iterrows():
type(r['age']) # 원래 int 였어도 object 일 수 있음
itertuples 는 컬럼별 dtype 보존.
2. row 수정해도 원본에 반영 안 됨
for _, r in df.iterrows():
r['age'] = r['age'] + 1 # ❌ 원본 df 안 바뀜
3. 매우 느림
CPython 루프 + Series 생성 비용.
items, 컬럼 순회
for name, col in df.items():
print(name, col.dtype, col.sum())
이건 보통 빠르고 의미가 명확.
진짜로 행 단위 처리가 필요할 때
apply(fn, axis=1): iterrows 보다 빠름itertuples(): 가장 빠른 Python 루프- numpy / numba / cython : 더 빠르게
# apply
df['c'] = df.apply(lambda r: r['a'] + r['b'], axis=1)
# numpy 벡터화 (가장 빠름)
df['c'] = df['a'].values + df['b'].values
# 한 번의 함수가 모든 입력을 받게
@np.vectorize
def my_fn(a, b):
return a + b
df['c'] = my_fn(df['a'], df['b'])
그래도 iterrows 가 필요한 경우
- API 가 dict / NamedTuple 입력을 요구
- 디버깅 / 한 번만 도는 작은 데이터
- 외부 시스템에 한 행씩 전송
💬 댓글