본문 바로가기

Programing Language/Python

[pandas] pd.DataFrame.to_csv()를 excel에서 열었을 때 한글 깨짐

반응형

Problem

문제는 심플하다. 아마 메모장이나 python, R 등에서 열었으면 아무 문제가 발생하지 않았을 텐데, 유독 excel에서만 발생한다.
원인은 엑셀에서 파일을 열 때 기본 인코딩인 cp땡땡땡 때문에 발쌩하는 문제이다. US Windows에선 CP1252 한국 windows에선 CP949 등에서 발생하는 고질적인 문제이다. CP949는 한글을 표현하기 위한 codepage이다. 우리는 codepage를 적합한 encoder/decoder를 통해서 입력/출력을 하게 된다 익숙한 codepage들을 예로 들자면 전세계 표준인 utf-8이나 컴퓨터 최초의 인코딩 방식인 ascii 등이 있을 수 있다.

CP949는 한글을 표현하기 위한 euc-kr의 확장 버전으로 한 문자를 2byte를 이용하여 표현한다. 더욱더 다양한 문자들을 모두 표현하기 위한 utf-8은 많은 문자를 표현하기 위한 만큼 한 문자를 3byte로 표현한다. 여기서 발생하는 문제가 바로 인코딩 형식의 차이에서 글자 단위를 제대로 인식하지 못하는 것이다.

cp949euc-kr로 입출력 할 때는 2byte 단위로 입출력을 하게되지만, utf-8단위로 입출력을 할 때는 3byte 단위로 입력하기 때문에, 문자를 제대로 이해하지 못한다. 이는 비단 excel 뿐 아니라, 인코딩이 다르게 설정되어있는 뷰어나 그 외 입출력 프로그램에서 흔히 발생할 수 있는 문제이다.

Solution

원인이 인코딩이니, 단순히 encoding을 바꿔주면 된다. 윈도우에 맞게 .to_csv(, encoding='cp949')를 해도 해결이 되지만, 이는 부분적 해결책이다. 이런 경우에는 또 역문제가 발생할 수도 있다. 다시 python에서 파일을 열때 encoding 옵션을 주지 않으면 또 깨지는 현상이 발생할 수 있어서 반쪽 짜리 해결책이다.
최선의 해결책은 byte order mark (BOM)을 사용하는 것이다.

BOM은 문서 앞단에서 해당 문서는 한 글자가 몇 바이트로 작성되었는지를 명시해 준다. 따라서 한 문자를 표현하는데 서로 다른 byte를 쓰는 인코딩들 사이에서 발생할 수 있는 문제를 해결해 준다. 이를 지원하는 encoding uption이 바로 utf-8-sig이다. 따라서 다음과 같은 옵션을 사용하면 상호간에 아무 문제가 발생하지 않을 수 있다. 여기서 "sig"는 "signature의 준말이다.

pd.DataFrame.to_csv(, encoding='utf-8-sig')
반응형