1. CSV 파일이란?
🚀 Comma Separated Values의 약자로 '콤마로 분리한 값들'
🚀 데이터베이스나 스프레드시트 데이터를 저장하기 위해서 사용하는 형식
⚡️ 내부는 실제 콤마(,)를 이용해서 모든 항목이 구분되어 있으며
콤마로 구성된 각 항목들이 테이블을 구성하는 각각의 데이터가 되는 방식
⚡️ 메모장에서는 텍스트로, 엑셀에서는 각 셀로 나누어서 보임
🚀 utf-8 형식으로 저장된 csv의 경우, 엑셀에서는 기본읽기로는 한글이 깨지는 경우가 있음
➡️ 한컴 cell에서는 에러없이 잘 열림
1) 단점 ( 엑셀 형식의 파일과 비교했을 때 )
a. 값에 유형이 없음. 모든 것은 다 문자열
b. 글꼴 크기나 색상을 설정할 수 없음
c. 여러 개의 워크시트를 가질 수 없음
d. 셀의 너비나 높이를 지정할 수 없음
e. 셀을 병합할 수 없음
f. 그림이나 차트를 포함할 수 없음
2) 장점
a. 단순함
b. 많은 프로그램에서 지원을 하고, 텍스트 편집기에서 볼 수 있으며, 스프레드 시트 데이터를 표현하는 간단한 방법
3) 주의점
⚡️ 텍스트로 구성되어 있어서, 각 줄에 대해 split(',')을 호출하여 쉼표로 구분된 값에서 문자열 리스트를 얻을 수 있음
➡️ csv 파일의 모든 쉼표가 두 셀의 경계를 나타내지 않고, 값의 일부인 경우도 있음
➡️ 이런 잠재적인 문제 때문에 csv 파일을 읽거나 쓸 때 csv 모듈을 사용하는 것이 좋음
2. CSV 파일 읽기
🚀 csv 파일은 쉼표(,)로 데이터가 구분되어 있어서 문자열 처리 메소드를 활용하면 별도의 외부 모듈이 없이도 충분히 읽을 수 있음
🚀 한 줄에 한 데이터가 있기 때문에 readline() 메소드로 한 줄씩 읽음
🚀 콤마(,)로 분리하기 위해서 split() 메소드를 이용
student_list = []
with open('../input_2/학생명단.csv', 'rt', encoding='cp949') as file:
file.readline() # 학번, 이름, 주소, 연락처
# readlines()는 한꺼번에 모두 읽고 커서가 맨 끝에 있어 더 이상 읽을 게 없어짐
while True:
line = file.readline()
if not line: # 더 이상 읽을 내용이 없으면 반복문을 빠져 나옴.
break
student = line.split(',') # 안 넣으면 하나의 문자열로 생성되기 때문
student_list.append(student)
print(student_list) # 리스트 안에 리스트가 들어가 있는 형태
'''
[['10101', '김승별', '서울시 영등포구', '010-1111-1111\n'],
['10102', '박나라', '서울시 여의도구', '010-2222-2222\n'],
['10103', '최태욱', '서울시 강남구', '010-3333-3333\n'],
['10104', '민기홍', '인천시 계양구', '010-4444-4444\n'],
['10105', '이명숙', '경기도 과천시', '010-5555-5555\n']]
'''
📌 csv 파일을 사용하다 보면 간혹 큰 따옴표(")를 이용해서 텍스트를 묶는 경우가 있음
➡️ 큰 따옴표를 제거하기 위해서 회원명에 추가로 strip() 메소드를 사용
member_list = []
with open('../input_2/회원명단.csv', 'rt', encoding='cp949') as file:
file.readline()
while True:
line = file.readline()
if not line:
break
member = line.split(',')
member[0] = member[0].strip('"') # 큰 따옴표를 제거
member_list.append(member)
print(member_list)
'''
[['강나라', '필라테스', '25일\n'], ['나유라', '수영', '25일\n'], ['이상기', '헬스', '15일\n']]
'''
👾 member[0]에는 큰 따옴표가 포함된 회원명이 저장되어 있기 때문에 member[0].strip('"')으로 큰 따옴표를 제거
📌 인코딩 시 영어는 문제가 없는데 한글의 경우 표현하는 방식이 2가지
- cp949 : 윈도우의 기본 인코딩. 예전 방식. 한글에만 특수화된 한국에서만 사용. 모든 한글을 표현하지 못함.
- uft-8 : 파이참의 기본 인코딩. 상대적으로 새로운 방식. 한글 및 기타 외국어 문자를 하나의 인코딩으로 모두 표현하기 개발
3. CSV 모듈
1) csv 모듈로 csv 파일 생성하기
🚀 import csv 를 통해서 csv 파일을 쉽게 처리할 수 있는 csv 모듈을 사용
import csv
# w모드로 열고 생성된 파일 객체를 csv.writer() 메소드에 전달
# 그러면 csv 파일을 생성할 수 있는 객체가 생성되는데 이 객체를 이용해서
# writerow() 메소드를 호출하면 csv 파일에 데이터를 저장할 수 있음
with open('../output_02/차량관리_01.csv', 'w', newline='', encoding='cp949') as file:
# delimiter=',' : ,콤마로 데이터 구분. tab을 사용하는 경우도 있음.tsv.
csv_maker = csv.writer(file, delimiter=',')
csv_maker.writerow([1, '08러1234', '2020-10-20,14:00'])
csv_maker.writerow([2, '25다1234', '2020-10-20,14:10'])
csv_maker.writerow([3, '28하1234', '2020-10-20,14:20'])
print('차량관리_01.csv 파일이 생성되었습니다.')
2) csv 모듈로 csv 파일 읽기
🚀 csv 파일을 읽기 위해서는 r 모드로 파일을 열고 생성된 파일 객체를 csv.reader() 메소드에 전달
🚀 csv.reader() 메소드는 csv 파일을 읽고 그 내용을 읽고 저장한 객체 iterator를 반환
with open('../output_02/차량관리_01.csv', 'r', newline='', encoding='cp949') as file:
csv_reader = csv.reader(file, delimiter=',')
for line in csv_reader:
print(line)
'''
['1', '08러1234', '2020-10-20,14:00']
['2', '25다1234', '2020-10-20,14:10']
['3', '28하1234', '2020-10-20,14:20']
'''
3) reader 객체
🚀 csv 모듈은 별도의 설치없이 사용가능
🚀 csv 모듈을 사용해서 csv 파일을 읽으려면 다른 텍스트 파일처럼 open() 함수로 파일을 열어야 함
import csv
example_file = open('../input_2/example.csv', encoding='cp949') # mode를 생략하면 rt가 기본값
# read() 대신 csv.reader() 함수에 전달. reader() 객체가 반환.
example_reader = csv.reader(example_file)
# list로 변환하여 값에 접근.
print(example_reader) # <_csv.reader object at 0x100eadcb0>
example_data = list(example_reader)
print(example_data)
print(example_data[0][1]) # Apples
example_file.close() # with 사용한 것이 아니기 때문에 닫아줘야 함
4) for 반복문을 활용해 reader 객체로부터 데이터 읽기
🚀 csv 파일이 큰 경우에는 전체 파일을 한 번에 메모리에 로드하지 않고 for 반복문에서 reader 객체 사용
🚀 reader 객체는 한 번만 사용가능하기 때문에 다시 사용하려면 새로 reader 객체 생성
example_file = open('../input_2/example.csv', encoding='cp949')
example_reader = csv.reader(example_file)
print('example.csv 출력')
for row in example_reader:
# 각 행의 번호를 얻으려면 reader 객체의 line_num 변수를 사용
print(f'Row #{str(example_reader.line_num)} {str(row)} {str(row[0])}')
example_file.close()
print('=' * 20)
5) writer 객체
🚀 writer 객체를 사용하면 데이터를 csv 파일에 저장할 수 있음
output_file = open('../output_02/output.csv', 'w', newline='', encoding='cp949')
# newline = '' : 빈줄이 들어가는 것 방지
output_writer = csv.writer(output_file) # csv.writer에 전달할 객체 생성.
output_writer.writerow(['spam', 'eggs', 'bacon', 'ham']) # writer.writerow() : 리스트에 인자를 전달
output_writer.writerow(['hello, world!', 'eggs', 'bacaon', 'ham'])
output_writer.writerow([1, 2, 3, 3.141592, 4])
output_file.close()
4. 키워드 인자 delimiter와 lineterminator
🚀 탭문자로 셀을 구분하고 줄 간격을 한 줄씩 띄우려는 상황이라면 구분자(delimiter)와 줄 끝 문자(lineterminator)를 변경
🚀 delimiter의 기본값은 쉼표이고, lineterminator의 기본값은 개행문자
🚀 셀들이 탭으로 구분되어 있기 때문에 탭으로 구분된 값을 의미하는 .tsv 파일 확장자 사용
csv_file = open('../output_02/example.tsv', 'w', newline='', encoding='cp949')
csv_writer = csv.writer(csv_file, delimiter='\t', lineterminator='\n\n')
csv_writer.writerow(['apples', 'oranges', 'grapes'])
csv_writer.writerow(['eggs', 'bacon', 'ham'])
csv_writer.writerow(['spam', 'spam', 'spam', 'spam', 'spam', 'spam'])
csv_file.close()
5. csv 객체의 DictReader와 DictWriter
🚀 헤더 행이 있는 csv 파일의 경우 reader나 writer 객체보다 DictReader나 DictWriter 객체를 사용하는 것이 작업하기 편함
⚡️ DictReader 객체는
a. row를 딕셔너리 객체로 설정하고
b. 첫 번째 행에 있는 정보를 건너 뜀
c. 첫 번째 행에 있는 정보를 키값으로 사용
example_file = open('../input_2/example_with_header.csv', encoding='cp949')
example_dict_reader = csv.DictReader(example_file)
print('example_with_header.csv 출력')
for row in example_dict_reader:
#print(row)
print(f'{row["Timestamp"]}, {row["Fruit"]}, {row["Quantity"]} ')
print('=' * 20)
🚀 헤더 행이 없는 파일의 경우 DictReader() 생성자의 두 번째 인자로 헤더 이름을 지어서 전달
example_file = open('../input_2/example.csv')
example_dict_reader = csv.DictReader(example_file, ['time', 'name', 'amount'])
print('example.csv 출력')
for row in example_dict_reader:
print(f'{row["time"]}, {row["name"]}, {row["amount"]} ')
print('=' * 20)
⚡️ DictWriter 객체는 csv 파일을 생성하기 위해 딕셔너리를 사용
- 파일에 헤더 행을 넣고 싶으면 writeheader()를 호출
- writerow() 메서드를 호출하여 각 행을 쓸 수 있는데, 이 때 딕셔너리를 사용
➡️ 딕셔너리의 키는 헤더이고, 딕셔너리의 값은 파일에 쓰려는 데이터가 들어감
output_file = open('../output_02/output_with_header.csv', 'w', newline='', encoding='cp949')
output_dict_writer = csv.DictWriter(output_file, ['Name', 'Pet', 'Phone'])
output_dict_writer.writeheader()
output_dict_writer.writerow({'Name': 'Alice', 'Pet': 'cat', 'Phone': '555-1234'})
output_dict_writer.writerow({'Name': 'Bob', 'Phone': '555-9999'})
# 누락된 키는 빈 상태로 나옴.
output_dict_writer.writerow({'Phone': '555-5555', 'Name': 'Carol', 'Pet': 'dog'})
# 순서는 중요하지 않음.
output_file.close()
'Programming Language > Python' 카테고리의 다른 글
[Python] 공공데이터 활용한 JSON API 예제 (2) | 2024.03.05 |
---|---|
[Python] JSON 파일 입출력 | 인코딩(encoding) 및 디코딩(decoding), API (2) | 2024.03.05 |
[Python] mutable/immutable, % 연산자, 삼항 조건연산자, 지역변수/전역변수 (0) | 2024.03.03 |
[Python] 파일과 경로, 파일 열기, 파일 닫기, 파일 생성, 파일 입출력, pickle (0) | 2024.03.03 |
[Python] 클래스 변수, 클래스 메소드, 정적 메소드, 상속 (0) | 2024.03.03 |