안녕하세요! 네로입니다. 블로그를 손 놓기가 싫어서... 뭘 쓸까 하다가, 개발이든 연구든 데이터 다루는 작업을 하다보니 자주 사용하는 코드와 요령들이 있더라구요. 그래서 그러한 내용들을 좀 보기 쉽게 기록겸, 공유겸 적어두려고 합니다. 이게 그 첫번째 게시물이 되겠네요. Python언어를 기반으로 작성을 할거고, 초보분들이 따라하시기 좋게 작성이 될 겁니다.
흔히, 데이터라고 하면 표 모양으로 구조화되어 있는 엑셀 파일 등을 떠올리게 될 겁니다. 이러한 표 데이터를 다른 사람에게 전달하거나 내가 보기 좋게 저장하는 과정에서 CSV 파일을 많이 활용하게 되는데요, 오늘은 이 CSV 파일을 Python으로 불러오고 쓰는 방법(들)을 간단히 정리해보겠습니다.
CSV 파일이란?
CSV란, Comma-seperated values의 줄임말로, 풀네임에서 알 수 있듯이 CSV 파일은 comma, 즉 쉼표로 정보가 구분되어져 있는 파일을 의미합니다. 예를 들면, 이렇게 생긴 파일입니다.
이걸 엑셀 파일로 열면, 아래처럼 보기 좋게 보여줍니다. 아마 csv 파일을 아래와 같이 엑셀 파일 형태로 많이 봤을겁니다.
그래서 CSV는 엑셀 파일 아니야? 라고 생각하시는 분들이 간혹 있는데, CSV는 정보가 콤마로 구분되어져 있다는 개념 뿐이고 실제로 CSV이지만 .csv가 아닌 .txt로 저장되어 있는 경우도 종종 있습니다. 하지만, 엑셀이 깔려져 있는 컴퓨터에서는 .csv파일들을 엑셀로 기본으로 보여주기 때문에 그냥 엑셀 파일 같은거구나~ 정도로 받아들여도 크게 문제는 없습니다. (정확히는 엑셀이 콤마로 정보를 구분하고 있는 .csv파일을 콤마를 기준으로 표로 보여주는 것입니다.)
저는 Python에서 CSV 파일을 읽고 쓸 때는 내장 모듈인 csv를 사용하는 방법을 소개합니다. 이 모듈에 대한 자세한 사용법은 여기를 참고하시면 되지만, 저는 아래의 방법으로 대부분 처리되긴 합니다. ㅎㅎ..
csv.reader
, csv.writer
객체를 활용한 방법
기본 모듈은 그냥 python을 설치하면 자동으로 설치되어 있는 모듈들을 의미합니다. 별도의 패키지 없이,
import csv
로 바로 불러올 수 있습니다.
csv.reader
를 이용해 csv파일 읽기
위에서 보여준 예시 파일들을 아래의 코드로 한 번 읽어볼겁니다. csv.reader
를 통해 csv 파일을 읽어들일 수 있고 그 아래의 for문을 통해서 각 행을 읽어볼 수 있습니다. ("data.csv"
자리에는 읽으려는 파일의 경로를 작성해 넣으시면 됩니다.)
import csv
f = open("data.csv", "r")
reader = csv.reader(f)
for row in reader:
print(row)
이렇게 프린트를 하면 다음과 같은 출력문이 나옵니다.
['id', 'name', 'price', 'amount']
['1', 'apple', '5000', '5']
['2', 'pencil', '500', '42']
['3', 'pineapple', '8000', '5']
['4', 'pen', '1500', '10']
위에서 보여드린 예시 csv 파일은 각 열의 이름을 포함한 행 (id, name, price, amount 등) 부터 총 5줄로 이루어져 있고, for문으로 reader
를 읽어들이면 각 행을 콤마로 구분한 리스트로 불러오게 됩니다. 첫번째로 나오는 리스트가 각 필드 명이니까 따로 변수로 저장해두고 그 다음으로 나오는 내용들을 데이터로 담아 사용하는 식의 활용이 가능하겠네요!
또는, 저렇게 각 행별로 처리하는 경우가 아니라 그냥 하나의 변수로 담고 싶다면 아래와 같은 트릭을 사용해볼 수 있습니다. reader
를 리스트로 변환하는 코드를 짠 것인데요,
import csv
f = open("data.csv", "r")
reader = csv.reader(f)
# for row in reader:
# print(row)
data = list(reader)
print(data)
결과로, data
변수에는 다음과 같은 2차원의 리스트로 저장이 됩니다.
[
['id', 'name', 'price', 'amount'],
['1', 'apple', '5000', '5'],
['2', 'pencil', '500', '42'],
['3', 'pineapple', '8000', '5'],
['4', 'pen', '1500', '10']
]
이렇게 변수로 파일 전체의 내용을 저장할 수도 있습니다. 그러면 데이터를 다룰 때마다 파일을 불러오지 않고 쉽게 사용할 수 있겠죠!
여기서 reader
를 통해 데이터를 읽어들일 수 있는데요,
import csv
f = open("data.csv", "r")
reader = csv.reader(f)
csv.writer
를 이용해 csv 파일 쓰기
혹은 CSV 파일을 만드려는 경우가 있을 수 있는데요, 위에 파일을 읽는 경우를 생각해보면 쓸 때에도 리스트 자료형을 활용하겠구나~ 하고 생각해볼 수 있습니다. 위의 예제 데이터를 저장해보도록 할게요.
먼저, 저장하려는 데이터를 리스트에 저장해 두고 csv 파일을 작성하는 방법입니다. writer
의 writerows
메소드를 사용하면, 2차원의 리스트를 한번에 csv로 저장할 수 있게됩니다.
import csv
data = [
['id', 'name', 'price', 'amount'],
['1', 'apple', '5000', '5'],
['2', 'pencil', '500', '42'],
['3', 'pineapple', '8000', '5'],
['4', 'pen', '1500', '10']
]
f = open("data2.csv", "w")
writer = csv.writer(f)
writer.writerows(data) ## 여기 주목!
f.close()
우리가 예제로 사용한 파일을 다시 만들어낼 수 있습니다.
한 줄씩 저장하는 방법은 다음과 같이 csv.writer
의 writerow
메소드를 사용하면 됩니다. 저장하려는 데이터를 변수에 따로 저장하지 않고 바로 csv 파일에 작성하고 싶을 때 주로 사용합니다.
import csv
data = [
['id', 'name', 'price', 'amount'],
['1', 'apple', '5000', '5'],
['2', 'pencil', '500', '42'],
['3', 'pineapple', '8000', '5'],
['4', 'pen', '1500', '10']
]
f = open("data2.csv", "w")
writer = csv.writer(f)
for row in data:
writer.writerow(row) ## 여기 주목!
f.close()
결과는 위의 경우와 같습니다! CSV 파일을 읽을 때나 쓸 때나 모두 각 행을 리스트로 표현한다는 점에만 유의한다면 쉽게 사용할 수 있을 것 같네요.
하지만, 위 방법들의 단점은 각 행이 리스트로 표현되다 보니 각 행별로 뜯어서 보면 몇번째 항목이 무슨 항목을 의미하는 것인지 직관적으로 알 수 없다는 것에 있습니다. 만약, 어떤 친절한 사람이 데이터를 알기 쉽게 다음과 같은 딕셔너리의 형태로 제공했다면 어떨까요?
[
{'id': '1', 'name': 'apple', 'price': '5000', 'amount': '5'},
{'id': '2', 'name': 'pencil', 'price': '500', 'amount': '42'},
{'id': '3', 'name': 'pineapple', 'price': '8000', 'amount': '5'},
{'id': '4', 'name': 'pen', 'price': '1500', 'amount': '10'}
]
딕셔너리를 통해서 각 행을 설명하는 부분이 좀 더 직관적이지만, 리스트로만 csv를 다룰 줄 아셨다면 이 경우엔 어떻게 해야할지 난감할 수 있습니다. 혹은, 스스로 csv 파일을 저렇게 분명히 표현하고 싶을 때도 있을거구요. 다음 섹션에서 어떻게 해볼 수 있는지 간단히 보겠습니다.
csv.DictReader
, csv.DictWriter
객체를 활용한 방법
저는 이 방법을 더 선호합니다. 각 행에 들어있는 정보가 각각 무엇을 의미하는지 직관적으로 알 수 있기 때문입니다. csv.DictReader
, csv.DictWriter
이 두 객체는 각각 csv 파일을 딕셔너리로 읽거나, 딕셔너리로 표현되어 있는 데이터를 csv 파일로 저장할 수 있게 해줍니다.
csv.DictReader
를 이용해 csv 파일 읽기
위의 csv.reader
를 읽을 때와 크게 차이는 없지만 보여지는 각 행의 모습이 딕셔너리로 보이게 됩니다. 좀 더 직관적이죠.
import csv
f = open("data.csv", "r")
reader = csv.DictReader(f)
for row in reader:
print(row)
f.close()
아래와 같이 출력됩니다. 항목의 이름을 key로, 그 값을 value로 갖게 되는 하나의 딕셔너리를 하나의 행으로 불러올 수 있게됩니다!
{'id': '1', 'name': 'apple', 'price': '5000', 'amount': '5'}
{'id': '2', 'name': 'pencil', 'price': '500', 'amount': '42'}
{'id': '3', 'name': 'pineapple', 'price': '8000', 'amount': '5'}
{'id': '4', 'name': 'pen', 'price': '1500', 'amount': '10'}
하나의 변수로 저장하는 위의 트릭도 사용할 수 있습니다.
import csv
f = open("data.csv", "r")
reader = csv.DictReader(f)
# for row in reader:
# print(row)
data = list(reader)
print(data)
f.close()
이렇게 딕셔너리들이 리스트에 담기게 됩니다.
[
{'id': '1', 'name': 'apple', 'price': '5000', 'amount': '5'},
{'id': '2', 'name': 'pencil', 'price': '500', 'amount': '42'},
{'id': '3', 'name': 'pineapple', 'price': '8000', 'amount': '5'},
{'id': '4', 'name': 'pen', 'price': '1500', 'amount': '10'}
]
csv.DictWriter
를 이용해 csv 파일 쓰기
파일을 쓸 때에도, csv.writer
를 쓸 때와 비슷하지만 fieldnames
를 DictWriter
를 불러올 때 인자로 같이 넘겨주어야 합니다. 그래야 내가 저장하려는 csv파일에 어떤 항목들이 있는지를 알 수가 있습니다. (csv.writer
는 그런걸 신경쓰지 않는겁니다. 그래서 각 행에 항목이 몇개가 있던 간에 콤마로 구분되어 있는 대로 그냥 저장하게 돼요.)
또한 writer.writeheader
를 통해서 파일의 첫번째 행에 항목 이름들을 넣어줄 것인지 결정할 수 있습니다. 아래 코드에 이 부분을 제거하게 되면 파일을 저장할 때 첫 행에 항목 이름이 작성이 안됩니다. 필요가 없다면 빼면 되겠습니다! 아래는 데이터 전체를 한번에 작성하는 방법이고, (writetrows)
import csv
fieldnames = ['id', 'name', 'price', 'amount']
data = [
{'id': '1', 'name': 'apple', 'price': '5000', 'amount': '5'},
{'id': '2', 'name': 'pencil', 'price': '500', 'amount': '42'},
{'id': '3', 'name': 'pineapple', 'price': '8000', 'amount': '5'},
{'id': '4', 'name': 'pen', 'price': '1500', 'amount': '10'}
]
f = open("data2.csv", "w")
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(data)
# for row in data:
# writer.writerow(row)
f.close()
아래는 한 줄씩 넣는 방법입니다. (writerow
)
import csv
fieldnames = ['id', 'name', 'price', 'amount']
data = [
{'id': '1', 'name': 'apple', 'price': '5000', 'amount': '5'},
{'id': '2', 'name': 'pencil', 'price': '500', 'amount': '42'},
{'id': '3', 'name': 'pineapple', 'price': '8000', 'amount': '5'},
{'id': '4', 'name': 'pen', 'price': '1500', 'amount': '10'}
]
f = open("data2.csv", "w")
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
# writer.writerows(data)
for row in data:
writer.writerow(row)
f.close()
이렇게 파이썬의 기본 모듈을 가지고 csv 파일로부터 깔끔하게 데이터를 불러올 수가 있습니다. 읽을 때는 비교적 쉽지만, 데이터를 가공해서 저장하는 입장이라면 csv 파일을 쓸 때에 내가 저장하려는 정보를 변수에 어떻게 담아야 하는지 주목하셔야 합니다. csv.writer
를 이용할 경우에는 각 행이 리스트로, csv.DictWriter
를 이용할 경우에는 딕셔너리로 두어야 한다는 점을 유의해주세요! 변수에만 잘 저장한다면 csv 파일을 쓰는 것은 크게 문제가 되지 않습니다.
사실 csv 파일은 pandas라는 패키지를 통해서 좀 더 효율적이고, 직관적으로 읽고 쓸 수 있습니다. 이 내용은 추후에 다뤄보도록 할게요!
'Python > 데이터 다루기' 카테고리의 다른 글
Python으로 json 파일 읽기/쓰기: json 모듈 활용법 (0) | 2022.02.11 |
---|