학인시 대비 마지막입니다. 사실 교재에 비해 좀 허술한 것 같아 약간 불안하긴 한데 어떻게든 되겠죠.
이번에는 csv 파일을 읽고 쓰는 방법에 대해 알아보겠습니다.
csv 라이브러리
csv는 .csv 형식의 파일(콤마로 구분되어있는 데이터들)을 읽고 쓰기에 특화된 모듈입니다.
python 설치 시 자동으로 설치되기도 합니다.
import csv
로 불러올 수 있습니다.
csv 데이터 다루기 (리스트)
리스트를 활용해 csv를 다루는 법을 알아보겠습니다. csv.reader, csv.writer 객체를 활용할 수 있습니다.
| Name | Age | Height |
| John | 20 | 180 |
| Andrew | 25 | 177 |
| Bell | 18 | 168 |
다음과 같은 data.csv 파일을 예시로 설명하겠습니다.
파일 읽기는 csv.reader를 통해 가능합니다.
이전에 텍스트 프로세싱 한 것처럼 파일을 열고, 이를 csv.reader를 이용해 객체로 저장하면 됩니다.
import csv
f = open('data.csv', 'r', encoding='cp949')
reader = csv.reader(f)
이렇게 불러올 수 있고, 현재 reader는 객체 상태이므로 이를 리스트로 바꿔주면 다루기가 편해질 겁니다.
크게 2가지 방법으로 읽을 수 있는데, for문을 활용해 행별로 읽거나, reader 전체를 list로 바꿀 수 있습니다.
# 1.
for row in reader :
print(row)
# 2.
list_reader = list(reader)
print(list_reader)
# 1.
['Name', 'Age', 'Height']
['John', '20', '180']
['Andrew', '25', '177']
['Bell', '18', '168']
# 2.
[['Name', 'Age', 'Height'],
['John', '20', '180'],
['Andrew', '25', '177'],
['Bell', '18', '168']]
2가지 모두 문제 없이 읽어올 수 있으므로 취향에 따라 택하면 될 것 같습니다.
for문 활용 시 한 행 한 행 읽을 수 있다는 장점이, list() 활용 시 전체를 이중 리스트로 한번에 옮길 수 있다는 장점이 있습니다.
next() 함수를 이용해서도 행의 내용을 읽을 수 있습니다.
주로 맨 위의 행(header row)을 읽을 때 사용합니다.
header = next(reader)
print(header)
['Name', 'Age', 'Height']
주의할 점은, 어떤 방식으로든 한 번 reader의 내용을 읽으면 그 내용은 reader에서 사라진다는 겁니다.
csv를 읽어봤으니 써보기도 해야겠죠. 데이터 쓰기는 csv.writer를 통해 가능합니다.
import csv
f = open('data2.csv', 'w', encoding='cp949')
writer = csv.writer(f)
읽어올 때와 똑같이 객체를 생성해주면 됩니다.
비어있는 data2.csv 파일을 생각해봅시다.
import csv
data1 = ['a11', 'a12', 'a13']
data2 = [['a21', 'a22', 'a23'],
['a31', 'a32', 'a33']]
with open('data2.csv', 'w', encoding='cp949', newline='') as f:
writer = csv.writer(f)
writer.writerow(data1)
writer.writerows(data2)
위와 같이 코드를 작성하였습니다. data1은 한 행만 있는 리스트고, data2는 여러 행이 있는 이중 리스트입니다.
우선 f.close()를 생략하기 위해 with문을 썼고, csv.writer는 무언가를 파일에 쓸 때마다 줄바꿈을 한번씩 더 하기 때문에 newline = ''이라는 부분을 추가하였습니다.
한 줄만 저장할 경우에는 writerow 메서드를 사용하면 되고, 여러 줄을 한 번에 저장할때는 writerows 메서드를 사용하면 됩니다.
혹은 for문을 이용해 여러 줄을 writerow 메서드로 저장할 수도 있겠죠.
for row in data2 :
writer.writerow(row)
# writer.writerows()와 결과 똑같음
csv 데이터 다루기 (딕셔너리)
리스트로 데이터를 저장하면 이 요소가 어떤 header row의 요소인지 헷갈릴 수 있습니다.
그래서 딕셔너리를 이용해 key와 value를 매칭시키면 훨씬 편하게 이를 확인할 수 있죠.
DictReader(), Dictwriter() 객체를 활용하면 csv의 데이터를 딕셔너리 형태로 다룰 수 있습니다.
import csv
f = open('data.csv', 'r', encoding='cp949')
reader = csv.DictReader(f)
for row in reader :
print(row)
{'Name': 'John', 'Age': '20', 'Height': '180'}
{'Name': 'Andrew', 'Age': '25', 'Height': '177'}
{'Name': 'Bell', 'Age': '18', 'Height': '168'}
아까와 같이 파일을 읽었지만, Dictreader를 사용했습니다.
이 경우 앞서 리스트로 나왔던 요소들이 딕셔너리 형태로 나오는 것을 알 수 있습니다. header row의 요소가 key, 그 밑의 행들이 value가 돼서 말이죠.
import csv
f = open('data.csv', 'r', encoding='cp949')
reader = csv.DictReader(f)
print(list(reader))
[{'Name': 'John', 'Age': '20', 'Height': '180'},
{'Name': 'Andrew', 'Age': '25', 'Height': '177'},
{'Name': 'Bell', 'Age': '18', 'Height': '168'}]
reader 객체를 리스트로 바꿔서 아예 출력해도 됩니다. 이 경우에는 딕셔너리들이 리스트로 묶여서 출력되죠.
쓰는 것도 똑같습니다. 다만 차이점은 fieldnames를 Dictwriter를 불러올 때 인자로 넘겨주어야 한다는 겁니다.
key 값들이 뭔지를 알려준다고 생각하면 될 것 같습니다.
import csv
fieldnames = ['Name', 'Age', 'Height']
data1 = {'Name': 'John', 'Age': 20, 'Height': 180}
data2 = [{'Name': 'Andrew', 'Age': 25, 'Height': 177},
{'Name': 'Bell', 'Age': 18, 'Height': 168}]
f = open('data2.csv', 'w', encoding='cp949', newline='')
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerow(data1)
f.close()
Name,Age,Height
John,20,180
다 똑같은데, 이번에는 writer.writeheader()라는 게 추가됐네요. 이 구문은 header row를 쓰냐 마냐를 결정합니다. 저 구문이 있으면 header row를 적고, 없으면 적지 않죠.
당연하게도 여러 줄을 적으려면 writerows 메서드를 쓰면 되겠죠.
f = open('data2.csv', 'w', encoding='cp949', newline='')
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writerows(data2)
f.close()
Andrew,25,177
Bell,18,168
이번에는 writeheader()를 뺐더니 header row가 사라진 걸 알 수 있죠.
writerow와 for문을 이용해 한 줄씩 여러 번 적는 것도 가능합니다.
f = open('data2.csv', 'w', encoding='cp949', newline='')
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerow(data1)
for row in data2 :
writer.writerow(row)
f.close()
Name,Age,Height
John,20,180
Andrew,25,177
Bell,18,168
학인시 대비는 이 정도로 마무리가 될 것 같습니다.ㅁ
'프로그래밍 > 파이썬 공부하기' 카테고리의 다른 글
| Python 공부하기 - 10 (텍스트 프로세싱) (1) | 2025.09.07 |
|---|---|
| Python 공부하기 - 9 (함수) (0) | 2025.09.07 |
| Python 공부하기 - 8 (지역, 전역변수) (0) | 2025.09.06 |
| Python 공부하기 - 7-2 (Numpy) (1) | 2024.06.30 |
| Python 공부하기 - 7-1 (Numpy) (6) | 2024.06.30 |