Post

Pandas read_csv() TXT 파일 읽기 완전 가이드

read_csv()로 텍스트 파일 읽을 때 옵션 설명

Pandas read_csv() TXT 파일 읽기 완전 가이드

읽기 후 기본 검증

1
2
3
4
5
6
7
8
9
10
# 데이터 로드 후 기본 검증
df = recommended_workflow('sample.txt', separator='\t')

if df is not None:
    print(f"Shape: {df.shape}")
    print(f"Columns: {list(df.columns)}")
    print(f"Null values: {df.isnull().sum().sum()}")
    print(f"\n첫 3행:\n{df.head(3)}")
else:
    print("파일 읽기 실패: 수동 전처리 필요")

기본 개념과 설정


인코딩 이해와 설정

인코딩이란?

파일 인코딩은 텍스트 데이터를 바이트로 저장하는 방식임. 잘못된 인코딩으로 파일을 읽으면:

  • 문자가 깨지거나 오류가 발생함
  • 특히 한글이나 특수문자에서 문제가 자주 발생함

주요 인코딩 옵션

인코딩설명사용 상황예시
utf-8유니코드 표준, 전 세계 문자 지원최신 파일, 국제적 사용영어, 한글, 일본어, 이모지 등
cp949한국어 Windows 기본 인코딩한국 Windows에서 생성된 파일엑셀에서 저장한 CSV
euc-kr한국어 Unix/Linux 인코딩구형 한국 시스템과거 웹사이트, 구형 DB
ascii영문자와 숫자만 지원영어만 포함된 파일로그 파일, 설정 파일
latin1서유럽 문자 지원유럽 언어 파일프랑스어, 독일어 등

인코딩 확인 방법

1
2
3
4
5
6
7
# 파일 인코딩 추측 (chardet 라이브러리 사용)
import chardet

with open('파일.txt', 'rb') as f:
    raw_data = f.read()
    result = chardet.detect(raw_data)
    print(f"감지된 인코딩: {result['encoding']}, 신뢰도: {result['confidence']}")

사전 파일 분석 (필수)

파일을 읽기 전에 구조를 먼저 확인하는 것이 중요함:

  • 구분자 종류 파악 (탭, 파이프, 쉼표 등)
  • 인코딩 추정
  • 특수문자나 따옴표 사용 패턴 확인
1
2
3
4
5
6
# 파일 구조를 먼저 확인
with open('파일.txt', 'r', encoding='utf-8') as f:
    for i, line in enumerate(f):
        print(f"Line {i+1}: {repr(line)}")
        if i >= 4:  # 처음 5줄만 확인
            break

출력 예시:

1
2
3
Line 1: 'name\tdescription\tage\n'
Line 2: 'John\t"Software Engineer"\t25\n'
Line 3: 'Jane\t"Data Scientist"\t30\n'

단계별 파일 읽기 워크플로우

체계적인 접근으로 대부분의 파일 읽기 문제를 해결할 수 있음:

  • 1단계부터 순서대로 시도
  • 각 단계에서 실패하면 다음 단계로 진행
  • 성공하면 즉시 종료
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import pandas as pd
import csv

def check_pandas_version():
    """pandas 버전이 1.3.0 이상인지 확인"""
    try:
        # pandas 1.3.0부터 on_bad_lines 매개변수 지원
        pd.read_csv.__code__.co_varnames
        return 'on_bad_lines' in pd.read_csv.__code__.co_varnames
    except:
        return False

def recommended_workflow(filepath, separator='\t'):
    """단계별 파일 읽기 워크플로우"""
    
    # 1단계: 기본 시도 (UTF-8, 기본 옵션)
    try:
        df = pd.read_csv(filepath, sep=separator, encoding='utf-8')
        print("1단계 성공: 기본 설정으로 읽기 완료")
        return df
    except UnicodeDecodeError:
        print("1단계 실패: UTF-8 인코딩 문제")
    except Exception as e:
        print(f"1단계 실패: {str(e)[:50]}...")
    
    # 2단계: 인코딩 변경
    for encoding in ['cp949', 'euc-kr', 'latin1']:
        try:
            df = pd.read_csv(filepath, sep=separator, encoding=encoding)
            print(f"2단계 성공: {encoding} 인코딩으로 읽기 완료")
            return df
        except Exception:
            continue
    
    # 3단계: 관대한 설정
    try:
        if check_pandas_version():
            # pandas 1.3.0 이후
            df = pd.read_csv(filepath,
                            sep=separator,
                            encoding='utf-8',
                            on_bad_lines='skip',
                            quotechar='"')
        else:
            # pandas 1.3.0 이전
            df = pd.read_csv(filepath,
                            sep=separator,
                            encoding='utf-8',
                            error_bad_lines=False,
                            warn_bad_lines=True,
                            quotechar='"')
        print("3단계 성공: 관대한 설정으로 읽기 완료")
        return df
    except Exception as e:
        print(f"3단계 실패: {str(e)[:50]}...")
    
    # 4단계: 고급 옵션 적용
    try:
        if check_pandas_version():
            df = pd.read_csv(filepath,
                            sep=separator,
                            encoding='utf-8',
                            quoting=csv.QUOTE_NONE,
                            escapechar='\\',
                            on_bad_lines='skip')
        else:
            df = pd.read_csv(filepath,
                            sep=separator,
                            encoding='utf-8',
                            quoting=csv.QUOTE_NONE,
                            escapechar='\\',
                            error_bad_lines=False)
        print("4단계 성공: 고급 옵션으로 읽기 완료")
        return df
    except Exception as e:
        print(f"모든 단계 실패: 수동 전처리 필요")
        return None

# 사용 예시
df = recommended_workflow('문제파일.txt', separator='|')

핵심 권장사항

파일 읽기 성공을 위한 3단계:

  1. 워크플로우 활용: recommended_workflow() 함수로 체계적 접근
  2. 결과 검증: shape, columns, null values 즉시 확인
  3. 문제 시 대응: 특수한 경우는 고급 옵션 활용

기억할 점: 90% 이상의 파일은 워크플로우만으로 해결됨

추가 팁:

  • 파일 크기 > 1GB: 청크 처리 또는 dtype 최적화 필수
  • 반복 작업: 한 번 성공한 설정을 함수로 저장해서 재사용
  • 프로덕션 환경: 에러 로깅과 함께 try-except 구문 활용

기본 읽기 방법과 예시


탭 구분 파일 (TSV) - 가장 일반적

입력 파일 (sample.txt):

1
2
3
4
name	description	age
John	Software Engineer	25
Jane	Data Scientist	30
Bob	Product Manager	35

읽기 코드:

1
2
3
4
5
import pandas as pd

df = pd.read_csv('sample.txt', 
                 sep='\t',
                 encoding='utf-8')

결과물:

namedescriptionage
JohnSoftware Engineer25
JaneData Scientist30
BobProduct Manager35

파이프(|) 구분 파일

입력 파일 (data.txt):

1
2
3
name|description|age
John|Software Engineer|25
Jane|Data Scientist|30

읽기 코드:

1
2
3
df = pd.read_csv('data.txt', 
                 sep='|',
                 encoding='utf-8')

결과물:

namedescriptionage
JohnSoftware Engineer25
JaneData Scientist30

쉼표 구분 파일 (CSV) - 텍스트에 쉼표 포함

입력 파일 (complex.txt):

1
2
3
name,description,age
John,"He likes coding, gaming, and reading",25
Jane,"Works at Company, Inc.",30

읽기 코드:

1
2
3
4
df = pd.read_csv('complex.txt', 
                 sep=',',
                 quotechar='"',
                 encoding='utf-8')

결과물:

namedescriptionage
JohnHe likes coding, gaming, and reading25
JaneWorks at Company, Inc.30

읽기 결과 검증하기

파일을 성공적으로 읽은 후에는 항상 기본 검증을 수행해야 함:

1
2
3
4
5
6
# 앞서 읽은 데이터 검증
print(f"Shape: {df.shape}")
print(f"Columns: {list(df.columns)}")
print(f"Null values: {df.isnull().sum().sum()}")
print(f"\n첫 3행:\n{df.head(3)}")
print(f"\nData types:\n{df.dtypes}")

검증 체크리스트:

  • Shape가 예상과 일치하는가?
  • 컬럼명이 올바르게 읽혔는가?
  • 특수문자나 한글이 깨지지 않았는가?
  • 숫자 컬럼이 제대로 인식되었는가?

문제 해결과 고급 옵션


일반적인 문제들

워크플로우로 해결되지 않는 특수한 경우들:

문제 1: 특수한 따옴표 혼재

입력 파일 (quotes.txt):

1
2
3
name|quote
John|"He said 'Hello' and left"
Jane|'She replied "Thank you" back'

해결법:

1
2
3
4
df = pd.read_csv('quotes.txt', 
                 sep='|',
                 quotechar='"',  # 주로 사용되는 따옴표 지정
                 encoding='utf-8')

결과물:

namequote
JohnHe said ‘Hello’ and left
Jane‘She replied “Thank you” back’

문제 2: 텍스트 내 이중 따옴표 (doublequote)

입력 파일 (double_quotes.txt):

1
2
3
name|description
John|"He said ""Hello"" to me"
Jane|"She replied ""Thank you"""

원인:

  • Excel에서 CSV 저장 시 자주 발생
  • 텍스트 내 따옴표를 ““로 이스케이프

해결법:

1
2
3
4
5
df = pd.read_csv('double_quotes.txt', 
                 sep='|',
                 quotechar='"',
                 doublequote=True,  # 기본값이지만 명시적으로
                 encoding='utf-8')

결과물:

namedescription
JohnHe said “Hello” to me
JaneShe replied “Thank you”

문제 3: 첫 번째 행이 헤더가 아닌 경우

입력 파일 (no_header.txt):

1
2
3
John	Software Engineer	25
Jane	Data Scientist	30
Bob	Product Manager	35

해결법:

1
2
3
4
5
6
7
8
9
10
# 헤더가 없는 경우
df = pd.read_csv('no_header.txt', 
                 sep='\t',
                 header=None,  # 첫 행을 헤더로 사용하지 않음
                 names=['name', 'job', 'age'])  # 컬럼명 직접 지정

# 또는 헤더가 2번째 행에 있는 경우
df = pd.read_csv('file_with_title.txt', 
                 sep='\t',
                 header=1)  # 2번째 행(index 1)을 헤더로 사용

문제 4: 특정 행 건너뛰기

입력 파일 (with_comments.txt):

1
2
3
4
5
# 이 파일은 샘플 데이터입니다
# 생성일: 2024-01-01
name	description	age
John	Software Engineer	25
Jane	Data Scientist	30

해결법:

1
2
3
4
5
6
7
8
9
10
11
# 주석 행 건너뛰기
df = pd.read_csv('with_comments.txt', 
                 sep='\t',
                 skiprows=2,  # 처음 2행 건너뛰기
                 encoding='utf-8')

# 또는 특정 행 번호들 건너뛰기
df = pd.read_csv('mixed_file.txt', 
                 sep='\t',
                 skiprows=[0, 1, 5],  # 0, 1, 5번째 행 건너뛰기
                 encoding='utf-8')

고급 옵션 활용

quoting 레벨 제어

입력 파일 (quoting_test.txt):

1
2
3
4
name,age,salary,department
"John","25","50000","IT"
Jane,30,60000,"Sales"
"Bob",35,"70000",Marketing
quoting 옵션 요약
옵션설명동작 방식주요 특징사용 상황
QUOTE_MINIMAL필요한 경우만 따옴표 처리구분자나 특수문자가 있을 때만기본값, 가장 일반적일반적인 CSV/TSV 파일
QUOTE_ALL모든 필드를 따옴표로 처리모든 텍스트를 따옴표 안의 내용으로 인식안전하지만 성능 저하복잡한 텍스트 데이터
QUOTE_NONNUMERIC숫자가 아닌 필드만 따옴표 처리따옴표 없는 값을 숫자로 자동 변환숫자 타입 자동 변환숫자 데이터 중심 파일
QUOTE_NONE따옴표를 무시함따옴표를 일반 문자로 처리escapechar 필수, 주의 필요따옴표가 문자열인 경우
기본 사용법 (QUOTE_MINIMAL)
1
2
import csv
df = pd.read_csv('quoting_test.txt', quoting=csv.QUOTE_MINIMAL)

결과물:

nameagesalarydepartment
John2550000IT
Jane3060000Sales
Bob3570000Marketing

특수 구분자와 구조 문제

공백으로 구분된 파일:

1
2
3
4
# 여러 개의 공백으로 구분된 경우
df = pd.read_csv('space_separated.txt', 
                 sep=r'\s+',  # 정규표현식: 하나 이상의 공백
                 engine='python')  # 정규표현식 사용 시 필요

고정폭 파일 (Fixed Width):

1
2
3
4
# 각 컬럼이 고정된 폭을 가진 경우
df = pd.read_fwf('fixed_width.txt',
                 widths=[10, 20, 5],  # 각 컬럼의 폭
                 names=['name', 'description', 'age'])

여러 구분자가 섞인 경우:

1
2
3
4
# 탭과 공백이 섞인 경우
df = pd.read_csv('mixed_separators.txt',
                 sep=r'[\t\s]+',  # 탭 또는 공백들
                 engine='python')

실무 가이드


일반적인 오류와 해결법

디버깅과 검증

읽기 후 검증

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def validate_dataframe(df, filepath):
    """데이터프레임 검증 및 리포트"""
    print(f"=== {filepath} 읽기 결과 ===")
    print(f"Shape: {df.shape}")
    print(f"Columns: {list(df.columns)}")
    print(f"Dtypes:\n{df.dtypes}")
    print(f"Null values: {df.isnull().sum().sum()}")
    
    # 특수 문자 포함 셀 확인
    for col in df.select_dtypes(include=['object']):
        special_chars = df[col].str.contains('["\'\n\t|,]', na=False)
        if special_chars.any():
            print(f"'{col}' 컬럼에 특수문자 포함: {special_chars.sum()}개 행")
    
    # 샘플 데이터 출력
    print(f"\n첫 3행:\n{df.head(3)}")

일반적인 오류와 해결법

오류 메시지원인해결법관련 섹션
ParserError: Error tokenizing data불일치한 컬럼 수on_bad_lines='skip' (pandas ≥1.3) 또는 error_bad_lines=False (pandas <1.3)문제 2: 컬럼 수 불일치 오류
UnicodeDecodeError잘못된 인코딩encoding='cp949' 또는 'euc-kr' 시도인코딩 이해와 설정
Expected X fields, saw Y구분자 또는 따옴표 문제quotechar 설정 또는 on_bad_lines='skip'quotechar 설정
FileNotFoundError파일 경로 오류파일 경로와 존재 여부 확인사전 파일 분석
PermissionError파일 접근 권한파일 권한 확인 또는 관리자 권한 실행-
TypeError: 'x' object is not callablepandas 버전 호환성on_bad_lines 대신 error_bad_lines 사용단계별 파일 읽기 워크플로우

성능 최적화

메모리 효율적 읽기

다음 옵션들로 메모리 사용량을 줄이고 성능을 향상시킬 수 있음:

  • dtype 지정으로 메모리 절약
  • 필요한 컬럼만 선택
  • 행 수 제한으로 테스트 속도 향상
1
2
3
4
5
6
7
8
9
# 단일 파일 최적화 (chunksize 없이)
df = pd.read_csv('huge_file.txt',
                 sep='\t',
                 encoding='utf-8',
                 dtype={'id': 'int32', 'score': 'float32'},  # 메모리 절약
                 usecols=['id', 'name', 'score'],  # 필요한 컬럼만
                 nrows=100000,  # 행 수 제한
                 low_memory=False,
                 engine='c')  # C 엔진 사용

대용량 파일 청크 처리

메모리 부족 시 파일을 나누어 처리:

  • 청크 단위로 읽어서 메모리 절약
  • 각 청크별로 전처리 가능
  • 최종적으로 하나의 DataFrame으로 결합
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def process_large_txt(filepath, chunksize=10000, separator='\t'):
    """대용량 파일을 청크 단위로 처리"""
    chunks = []
    
    # pandas 버전에 따른 매개변수 설정
    chunk_params = {
        'filepath_or_buffer': filepath,
        'sep': separator,
        'encoding': 'utf-8',
        'chunksize': chunksize
    }
    
    if check_pandas_version():  # 위에서 정의한 함수 사용
        chunk_params['on_bad_lines'] = 'skip'
    else:
        chunk_params['error_bad_lines'] = False
    
    # chunksize 사용 시 iterator 반환됨
    chunk_iterator = pd.read_csv(**chunk_params)
    
    for chunk in chunk_iterator:
        # 각 청크 정제
        chunk_cleaned = chunk.dropna(how='all')
        chunks.append(chunk_cleaned)
    
    return pd.concat(chunks, ignore_index=True)

# 사용 예시  
df = process_large_txt('big_file.txt', chunksize=5000, separator='\t')
print(f"{len(df)} 행 로드됨")

This post is licensed under CC BY 4.0 by the author.