본문 바로가기

IT/빅데이타

[Pandas] iterrows()를 to_dict('records')로 바꾸면 어떤 점이 좋아질까?

반응형

Pandas로 ETL 작업을 하다 보면, DataFrame을 반복하며 각 행(row)을 처리해야 하는 순간이 자주 찾아옵니다.
이때 많은 초중급 개발자들이 자연스럽게 사용하는 방식이 바로 iterrows()죠.

하지만 DataFrame 처리량이 커지기 시작하면 성능이 급격히 저하되고, dtype 변질·병렬 처리 문제까지 겹쳐 유지보수가 어려워지곤 합니다.

그래서 실무에서는 iterrows() 대신 to_dict('records') 로 변환해 사용하는 방식이 더 효율적인 경우가 많습니다.
오늘은 두 방식의 장단점과 실무에서의 선택 기준을 정리해보겠습니다.


[1] iterrows() 사용 시 문제점

iterrows()는 각 행을 Pandas Series로 반환합니다.
문제는 Series로 반복하는 방식이 다음과 같은 단점을 가진다는 겁니다.

1. 성능이 매우 느림

Row-by-row 반복은 Python 레벨 Loop이기 때문에, 수만·수십만 행이 넘어가면 속도가 급격히 느려집니다.

2. dtype이 자주 깨짐

Series 변환 과정에서 숫자가 float로 바뀌거나, int64 → object로 캐스팅되는 일이 잦습니다.

3. 병렬처리에 불리

Series 객체는 pickle 성능이 좋지 않아 멀티프로세싱이나 병렬처리에 적합하지 않습니다.


[2] to_dict('records')로 바꿨을 때의 장점

to_dict('records')는 DataFrame 전체를 “list[dict]” 형태로 한 번에 변환합니다.

1. 압도적인 성능 향상

iterrows()보다 2배~20배 빠른 경우도 많습니다.
특히 ETL에서 수십만 행을 BigQuery로 업로드할 때 체감 속도 차이가 큽니다.

2. 코드 간결 + 직관적

기존:

 
for idx, row in df.iterrows(): process(row['a'], row['b'])

변경 후:

 
for row in df.to_dict('records'): process(row['a'], row['b'])

필요 없는 index 제거, row가 dict로 직관적으로 다뤄짐.

3. dtype 유지

Series 변환 없이 dict 형태로 변환되기 때문에 dtype이 변경될 가능성이 낮습니다.

4. 병렬 처리에 최적화

dict는 바로 pickle이 가능해, multiprocessing이나 multi-thread에서 유리합니다.


[3] 단점도 있다

to_dict('records')가 만능은 아닙니다.

1. 메모리 사용량 증가

전체 데이터를 한 번에 dict로 변환하기 때문에
수백만 행 이상 단위에선 메모리 부담이 있습니다.

해결책:

  • chunk 단위로 DataFrame을 나누기
  • 혹은 itertuples() 사용 (가장 빠르고 메모리 가벼움)

2. KeyError가 나기 쉬움

dict 기반이라 키 오타가 있으면 바로 에러가 발생합니다.
하지만 이는 오히려 버그를 일찍 발견할 수 있는 장점이기도 합니다.

3. pandas 벡터화 연산을 사용하는 게 더 빠른 경우가 존재

가능하면 loop 없이 벡터화하는 게 성능 최적화의 정석입니다.
둘 중 하나만 골라야 하는 상황이라면 to_dict('records')가 더 낫다는 의미지,
벡터화를 대체하는 것은 아닙니다.


-실무 기준 결론-

ETL 환경에서 다음과 같은 작업이 많다면 거의 무조건 to_dict('records')가 유리합니다.

  • API 또는 DB 업로드용 JSON 생성
  • row 기반 Python 처리
  • BigQuery insert_rows_json() 호출
  • multiprocessing 활용

실무에서의 추천 순서

방식설명
⭐ itertuples() 가장 빠르고 가벼움 (단, dict처럼 키 접근은 불가)
⭐ to_dict('records') ETL에서 균형 좋은 선택 (dict 기반 처리 필요 시)
❌ iterrows() 가장 느리고 dtype 불안정

# 정리

  • iterrows는 거의 쓰지 않는 것이 실무 정답
  • to_dict('records')는 성능·안정성·가독성 모두 향상
  • 대용량 처리 또는 병렬 처리 시 특히 강력
  • 메모리 이슈 있다면 itertuples()도 고려
반응형