Skip to main content

데이터 입출력

실무 데이터 분석은 파일에서 데이터를 불러오는 것으로 시작합니다. Pandas는 다양한 파일 형식을 지원하며, 각 형식에 맞는 읽기/쓰기 함수를 제공합니다. 대용량 파일을 효율적으로 처리하는 방법도 함께 다룹니다.

학습 목표

  • CSV, Excel, JSON, Parquet 파일을 읽고 쓸 수 있다
  • 읽기 옵션(인코딩, 구분자, 헤더 등)을 상황에 맞게 설정할 수 있다
  • chunksize를 활용하여 대용량 파일을 처리할 수 있다
  • 파일 형식별 특성과 적합한 사용 시나리오를 설명할 수 있다

왜 중요한가

데이터는 CSV, Excel, JSON, 데이터베이스 등 다양한 형태로 존재합니다. 각 형식의 특성을 이해하고 올바르게 읽어야 데이터 손실이나 인코딩 문제 없이 분석을 시작할 수 있습니다. 특히 수백 MB 이상의 대용량 파일은 일반적인 방법으로 읽으면 메모리 부족이 발생할 수 있습니다.

CSV 파일

읽기

import pandas as pd

# 기본 읽기
df = pd.read_csv('data.csv')

# 주요 옵션
df = pd.read_csv('data.csv',
    encoding='utf-8',           # 인코딩 (한글: 'cp949' 또는 'euc-kr')
    sep=',',                    # 구분자 (탭: '\t')
    header=0,                   # 헤더 행 번호 (없으면 None)
    names=['col1', 'col2'],     # 열 이름 직접 지정
    index_col='id',             # 인덱스로 사용할 열
    usecols=['col1', 'col3'],   # 읽을 열만 선택
    dtype={'age': 'int32'},     # 열별 dtype 지정
    na_values=['NA', '-', ''],  # 결측치로 인식할 값
    parse_dates=['date_col'],   # 날짜로 파싱할 열
    nrows=1000,                 # 상위 N행만 읽기
)
한글이 포함된 CSV 파일에서 UnicodeDecodeError가 발생하면 encoding='cp949' 또는 encoding='euc-kr'을 시도하세요. Windows에서 생성된 한글 CSV는 대부분 CP949 인코딩입니다.

쓰기

# CSV로 저장
df.to_csv('output.csv', index=False, encoding='utf-8-sig')
# utf-8-sig: Excel에서 한글이 깨지지 않는 BOM 포함 UTF-8

Excel 파일

# 읽기 (openpyxl 필요: pip install openpyxl)
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')

# 여러 시트 한 번에 읽기
sheets = pd.read_excel('data.xlsx', sheet_name=None)  # 딕셔너리 반환
for name, sheet_df in sheets.items():
    print(f"시트: {name}, 행 수: {len(sheet_df)}")

# 쓰기
df.to_excel('output.xlsx', index=False, sheet_name='결과')

# 여러 시트에 쓰기
with pd.ExcelWriter('output.xlsx') as writer:
    df1.to_excel(writer, sheet_name='요약', index=False)
    df2.to_excel(writer, sheet_name='상세', index=False)

JSON 파일

# 읽기
df = pd.read_json('data.json')

# orient 옵션 — JSON 구조에 따라 설정
df = pd.read_json('data.json', orient='records')
# records: [{"col1": val1, "col2": val2}, ...]
# columns: {"col1": [val1, val2], "col2": [val3, val4]}
# index: {"idx1": {"col1": val1}, "idx2": {"col1": val2}}

# 중첩 JSON 정규화
import json
with open('nested.json') as f:
    data = json.load(f)
df = pd.json_normalize(data, record_path='items',
                       meta=['id', 'name'])

# 쓰기
df.to_json('output.json', orient='records', force_ascii=False, indent=2)
# force_ascii=False: 한글 유지

Parquet 파일

# 읽기 (pyarrow 필요: pip install pyarrow)
df = pd.read_parquet('data.parquet')

# 특정 열만 읽기 (열 기반 형식의 장점)
df = pd.read_parquet('data.parquet', columns=['col1', 'col3'])

# 쓰기
df.to_parquet('output.parquet', index=False, compression='snappy')

파일 형식 비교

형식용도장점단점
CSV범용 데이터 교환사람이 읽을 수 있음, 호환성 높음dtype 미보존, 느린 I/O
Excel비즈니스 보고서서식/수식 보존, 다중 시트느림, 행 수 제한(~100만)
JSONAPI 응답, 설정중첩 구조 표현, 웹 친화적중복 키 이름으로 용량 큼
Parquet대용량 분석dtype 보존, 고압축, 빠른 I/O사람이 읽을 수 없음
데이터 분석 중간 결과를 저장할 때는 Parquet를 추천합니다. CSV 대비 5~10배 빠르고, dtype이 보존되며, 압축률도 높습니다.

대용량 파일 처리

# chunksize로 분할 읽기
chunks = pd.read_csv('large_data.csv', chunksize=10000)

results = []
for chunk in chunks:
    # 각 청크를 처리
    processed = chunk[chunk['value'] > 100]
    results.append(processed)

# 결과 합치기
df = pd.concat(results, ignore_index=True)
# 필요한 열만 읽어 메모리 절약
df = pd.read_csv('large_data.csv',
    usecols=['id', 'target', 'feature1'],
    dtype={'id': 'int32', 'feature1': 'float32'}
)

AI/ML에서의 활용

  • 학습 데이터 로드: Kaggle 데이터셋의 대부분은 CSV 형식입니다
  • 피처 스토어: 전처리된 피처를 Parquet으로 저장하면 재사용이 빠릅니다
  • API 데이터: JSON 응답을 DataFrame으로 변환하여 분석합니다
  • 실험 결과: 모델별 성능 지표를 Excel로 정리하여 공유합니다
사람이 직접 확인하거나 다른 도구와 공유해야 하면 CSV, 프로그래밍적으로 반복 사용하는 중간 데이터는 Parquet을 사용하세요. 100MB 이상의 데이터라면 Parquet이 압도적으로 유리합니다.
Pandas가 dtype을 추론할 때 청크 단위로 처리하면서 같은 열에 다른 타입이 발견될 수 있습니다. dtype 파라미터로 명시적으로 지정하거나 low_memory=False로 전체를 한 번에 읽으면 해결됩니다.

체크리스트

  • CSV, Excel, JSON, Parquet 파일을 읽고 쓸 수 있다
  • 인코딩, 구분자, 헤더 등 읽기 옵션을 상황에 맞게 설정할 수 있다
  • chunksize로 대용량 파일을 분할 처리할 수 있다
  • 파일 형식별 장단점을 이해하고 적합한 형식을 선택할 수 있다
  • Parquet의 장점을 설명하고 활용할 수 있다

다음 문서