본문 바로가기

파일 형식 백과사전

CSV를 열었더니 주소 뒷부분이 옆 칸으로, 값 속 쉼표 때문에 열이 밀리는 문제

이름과 주소가 잘 정리돼 있던 CSV를 프로그램으로 읽었더니,

주소 한 칸이 두 칸으로 쪼개지면서 그 뒤 금액까지 줄줄이 옆으로 밀려 버리는 경우가 있습니다.

데이터는 멀쩡한데 표만 어긋난 것처럼 보입니다.

 

범인은 대개 값 안에 들어간 쉼표입니다. CSV는 쉼표로 칸을 나누는 형식이라,

주소나 회사명처럼 값 자체에 쉼표가 들어 있으면

그 지점에서 칸이 하나 더 생겨 버립니다. 실제로 재현하고 바로잡아 보겠습니다.

 

이런 데이터에서 문제가 생깁니다

id, name, address, amount 네 칸짜리 CSV를 예로 들겠습니다.

그런데 주소 값 안에 상세 번지를 쉼표로 붙여 놓았습니다.

id,name,address,amount
1,김민수,서울시 강남구 역삼동, 123-4,50000
2,이서연,부산시 해운대구 우동, 5-6,30000

사람 눈에는 주소가 한 덩어리로 보이지만, CSV를 읽는 프로그램은 쉼표를 만날 때마다 칸을 나눕니다.

그래서 이 줄은 4칸이 아니라 5칸으로 쪼개집니다.

 

실제로 읽으면 이렇게 밀립니다

파이썬 pandas로 위 파일을 읽으면, 칸 수가 맞지 않아 값들이 한 칸씩 왼쪽으로 밀린 채 들어옵니다.

    id         name  address  amount
1  김민수  서울시 강남구 역삼동   123-4   50000
2  이서연  부산시 해운대구 우동    5-6   30000

원래 id에 있어야 할 1이 사라지고, name 칸에 이름이 아니라 다른 값이 들어간 것이 보입니다.

번지수 123-4가 amount(금액) 자리를 차지해 버렸습니다. 값 하나에 쉼표가 끼면 그 줄 전체의 칸이 어긋납니다.


왜 이런 일이 생길까

원인은 단순합니다. 헤더 줄은 쉼표가 3개라 4칸인데, 데이터 줄은 주소 속 쉼표까지 더해져 쉼표가 4개, 즉 5칸이 됩니다. 칸 수가 서로 다르니 읽는 쪽이 자리를 못 맞추는 것입니다.

헤더:    id,name,address,amount            → 4칸
데이터:  1,김민수,서울시 강남구 역삼동, 123-4,50000  → 5칸

 

해결: 쉼표가 든 값은 큰따옴표로 감싼다

CSV 규칙에는 이 상황을 위한 약속이 있습니다. 값 안에 쉼표가 있으면

그 값을 큰따옴표로 감싸는 것입니다. 그러면 따옴표 안의 쉼표는 칸 구분이 아니라 값의 일부로 취급됩니다.

id,name,address,amount
1,김민수,"서울시 강남구 역삼동, 123-4",50000
2,이서연,"부산시 해운대구 우동, 5-6",30000

이렇게 고친 파일을 다시 읽으면 4칸이 정확히 맞습니다.

   id name             address  amount
0   1  김민수  서울시 강남구 역삼동, 123-4   50000
1   2  이서연    부산시 해운대구 우동, 5-6   30000

주소가 쉼표를 포함한 채로 한 칸에 온전히 들어갔습니다.

 

애초에 저장할 때 막는 법

직접 파일을 만들 때는 따옴표를 일일이 붙일 필요가 없습니다. pandas의 to_csv나 파이썬 표준 csv 모듈로 저장하면, 값에 쉼표가 있을 때 알아서 큰따옴표로 감싸 줍니다.

import pandas as pd

df = pd.DataFrame({"id": [1], "address": ["서울시 강남구 역삼동, 123-4"]})
df.to_csv("out.csv", index=False)
# 저장 결과: 1,"서울시 강남구 역삼동, 123-4"  (자동으로 따옴표 처리됨)

문제는 보통 엑셀에서 손으로 편집하거나, 따옴표 처리를 하지 않는 방식으로 문자열을 이어 붙여 CSV를 만들 때 생깁니다. 값에 쉼표가 섞일 수 있는 데이터라면 저장을 도구에 맡기는 편이 안전합니다.

 

자주 묻는 질문

Q. 값 안에 큰따옴표까지 들어 있으면요?
그때는 큰따옴표를 두 번("") 겹쳐 씁니다. 이것도 to_csv나 csv 모듈이 자동으로 처리하므로 직접 신경 쓸 일은 드뭅니다.

 

Q. 쉼표 대신 다른 구분자를 쓰면 안 되나요?값에 쉼표가 유난히 많다면 탭으로 구분하는 TSV로 저장하는 방법도 있습니다. 다만 받는 쪽도 같은 구분자로 읽어야 하니 미리 맞춰 두어야 합니다.

 

Q. 이미 밀려서 저장된 데이터는 되살릴 수 있나요?
원본이 남아 있다면 따옴표를 넣어 다시 저장하면 됩니다. 밀린 결과만 남았다면 어느 값이 쪼개졌는지 일일이 확인해야 해서 복구가 번거로워집니다.

 

열이 밀리는 CSV는 파일이 깨진 것이 아니라 쉼표라는 구분자와 값이 충돌한 결과입니다.

값에 쉼표가 들어갈 수 있는 열(주소, 회사명, 메모)이 있다면

큰따옴표 규칙만 기억하면 됩니다. 지금 다루는 CSV에 그런 열이 있는지부터 살펴보세요.