이것도 알아야 하네?

[Python] csv 파일을 읽는 다양한 방법 본문

프로그래밍/데이터 분석

[Python] csv 파일을 읽는 다양한 방법

아직 갈 길이 먼 사람 2021. 11. 19. 00:25
728x90

csv 파일이란?

csv 파일이란 comma separated values 의 약자로 데이터를 저장하는 파일 형식 중 하나입니다. 이름에서 예측할 수 있듯이 record에 저장되는 값들이 ',(comma)'를 이용하여 나열되어 있습니다. 

 

csv파일 읽기

csv파일도 파일형식이기 때문에 (1) open() 구문을 사용하여 일반 파일처럼 읽고 쓸 수 있고, 추가로 Python에서는 (2) csv 파일을 처리할 수 있는 기능을 가진 모듈을 built-in으로 제공하기 때문에 해당 모듈을 사용하여 더욱 쉽고 직관적으로 csv 파일을 조작할 수 있습니다. 

// test.csv 내용
a,b,c
1,2,3
4,5,6

(1) open() 사용하기 

f = open(file_name)
...
f.close()

파일을 읽을 때는 open()을 사용하고, 다 사용하면 close()를 이용하여 닫아주어야 합니다. close()를 하지 않는다면 파일은 계속 열린 채로 존재하여 시스템 자원의 누수가 발생합니다. 당연히 아래의 모든 코드는, open()과 close() 조합 대신에 with open() 코드로도 대체 가능합니다. 

import os

file_name = 'test.csv'

if os.path.exists(file_name):
	f = open(file_name)

...

f.close()

위의 코드는 file_name의 파일이 존재할 때 해당 파일을 읽는 코드입니다. '...'으로 생략된 부분에 원하는 작업을 진행할 수 있습니다. 작업할 수 있는 예시로는 아래와 같습니다.

 

> 한 줄 읽기 

f = open(file_name)
f.readline()
f.close()

파일을 open()을 이용하여 읽은 후 readline()을 이용하여 파일에 있는 한 줄을 읽을 수 있습니다. 한 줄이라고 하믄, 현재 커서가 존재하는 위치에서부터 개행문자('\n')가 나올 때까지 입니다. 파일을 처음 open()으로 열면 커서가 첫 줄 맨 앞에 있으며, readline()을 사용하면 개행문자가 나올 때까지의 한 줄을 반환하고 커서는 그 다음 줄 맨 앞에 있게 됩니다. 

l = f.readline()
print(l)

line = l.split(',')
print(line)

line = l.strip().split(',')
print(line)

output:

a,b,c
['a', 'b', 'c\n']
['a', 'b', 'c']

파일을 연 후, 한 줄을 읽고 print 구문을 이용하면 a,b,c가 출력되지만, 실제 l에는 'a,b,c\n' 가 저장되어 있습니다. 이를 확인하기 가장 쉬운 방법은 strip()을 이용하여 실제로 어떤 값들로 구성되어있는 지 확인하는 것입니다. output의 두 번째 줄처럼 단순히 ',(comma)' 기준으로 문장을 나누면, 마지막 값에는 줄바꿈 문자가 들어가 있음을 알 수 있습니다. 이를 제거하기 위해서는 strip()을 사용해야합니다. 

 

> 한 줄씩 읽기

앞서 언급했듯이, readline()을 이용하는 경우 개행문자 단위로 커서의 이동이 발생하므로, readline()을 한 번 더 사용할 경우 같은 방식으로 읽은 줄의 다음 줄을 읽을 수 있습니다. 이를 확장시켜 루프를 사용한다면 문자가 있을 떄까지 한 줄씩 읽을 수 있습니다. 

lines = []
while(True):
	line = f.readline()
	if not line:
		break;
	lines += [line.strip().split(',')]
    
print(lines)

output:

[['a', 'b', 'c'], ['1', '2', '3'], ['4', '5', '6']]

 

> 한 번에 읽기

f = open(file_name)
f.readlines()
f.close()

루프를 사용하여 한 줄씩 읽는 것이 귀찮다면, readlines()를 이용하여 한 번에 파일에 있는 모든 문자를 읽을 수 있습니다.

lines = csv.readlines(f)
print(lines)

output:

['a,b,c\n', '1,2,3\n', '4,5,6\n']

한 줄씩 읽어 하나의 리스트 형태로 반환합니다. ','를 기준으로 나눠져 있지도 않고, 개행문자까지 들어있기 때문에 ',' 기준으로 개별 값을 얻고 싶다면 추가적인 코드 작성이 필요합니다.

 

(2) csv 모듈 사용하기

csv.reader(fileObject)

open()의 반환 값을 csv.reader()을 이용하면 readlines()처럼 파일에 존재하는 모든 문장을 한 번에 읽어오기 때문에 루프를 통해 한 문장씩 읽을 수 있습니다. 하지만, readlines()에서는 ',' 기준으로 구분되지 않고 개행문자까지 포함되어 한 문장을 다 읽었다면, csv.reader()는 자동으로 개행문자를 제외하고  ',' 기준으로 구분해서 읽기 때문에 조금 더 편리하게 사용할 수 있습니다. 예시 코드는 제가 애용하는 geeksforgeeks에 있는 내용을 포함하여 아래와 같이 작성하였습니다

www.geeksforgeeks.org/working-csv-files-python/

 

Working with csv files in Python - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

# importing csv module
import csv
  
# csv file name
file_name = "test.csv"
  
# initializing the titles and rows list
fields = []
rows = []
  
# reading csv file
with open(file_name, 'r') as csvfile:
    # creating a csv reader object
    csvreader = csv.reader(csvfile)
      
    # extracting field names through first row
    fields = next(csvreader)
  
    # extracting each data row one by one
    for row in csvreader:
        rows.append(row)
  
print(rows)

next()를 이용하면 한 줄을 읽을 수 있고, 해당 파일의 첫 줄이 field 이름일 때 사용할 수 있습니다.

output:

[['1', '2', '3'], ['4', '5', '6']]

코드 상에서 첫 줄은 field 이름들로 먼저 제거했기 때문에 첫줄을 제외한 값들만 들어있음을 알 수 있습니다. 

 

728x90
Comments