본문 바로가기

[20]개발/[B]AI

[Python] CSV 파일 읽고 쓰기 (Pandas)


파이선으로 어떤 과제를 수행하다 보면, CSV 형식의 파일을 읽고 써야 할 때가 많다. 이 때 여러가지 라이브러리를 동원하게 되는데, 이 중 제일 간단한 Pandas (판다스 라고 읽는다.) 와 CSV 형식에 대해 알아보도록 하자.

CSV란?


CSV(영어: comma-separated values)는 몇 가지 필드를 쉼표(,)로 구분한 텍스트 데이터 및 텍스트 파일이다. 확장자는 .csv이며 MIME 형식은 text/csv이다. comma-separated variables라고도 한다. 오래전부터 스프레드시트나 데이터베이스 소프트웨어에서 많이 쓰였으나 세부적인 구현은 소프트웨어에 따라 다르다. 그것들을 추가한 형태가 2005년 10월 RFC 4180에서 Informational(IESG의 외부에서 결정된 유용한 정보의 제공)로 사양이 문서화됐다. (https://ko.wikipedia.org/wiki/CSV_(%ED%8C%8C%EC%9D%BC_%ED%98%95%EC%8B%9D) c참고)

예를 들어 아래와 같은 테이블이 있다면,

연도

제조사

모델

설명

가격

1997

Ford

E350

ac, abs, moon

3000.00

1999

Chevy

Venture "Extended Edition"

4900.00

1999

Chevy

Venture "Extended Edition, Very Large"

5000.00

1996

Jeep

Grand Cherokee

MUST SELL!

air, moon roof, loaded

4799.00

CSV 형식은 아래와 같이 표현될 수 있다. 즉, 각 컬럼을 쉼표 혹은 공백(separator)로 구분하며, 모든 행을 나열한 파일 형식을 말한다. 단순한 txt 파일이기 때문에 텍스트에디터 등을 통해서 열수 있고, 스프레드시트(excel 등) 에서도 파일 open 이 가능하다.

연도,제조서,모델,설명,가격

1997,Ford,E350,"ac, abs, moon",3000.00

1999,Chevy,"Venture ""Extended Edition""","",4900.00

1999,Chevy,"Venture ""Extended Edition, Very Large""",,5000.00

1996,Jeep,Grand Cherokee,"MUST SELL! air, moon roof, loaded",4799.00

일반적인 Text 파일이므로 에디터에서 그냥 열리지만, 보기가 무척 불편하다. 더구나 공백값이 있을 경우 열을 맞춰 데이터를 확인하기는 거의 불가능하다. 따라서 이를 시각화하고 쉽게 수정할수 있는 기능이 필요하다.

(물론 엑셀로도 가능하지만 현업에서 다루는 대부분의 데이터는 그 사이즈가 매우 크고 - 100MB 이상 - 따라서 이런 CSV 파일을 엑셀로 열면 웬만한 PC 는 뻗어버린다. 그러나 동이란 파일을 판다스에서 읽으면 문제없이 잘 읽힌다. 이게 바로 판다스의 매력 :)

Pandas.read_csv()


Pandas (판다스, https://pandas.pydata.org/) 빅데이터 분석을 위한 파이선 라이브러리이다. 엑셀이나 텍스트 파일, SQL 데이터베이스에 등의 분석을 위해 사용할 수 있다. 사용이 쉽고, 빠르며, 업데이트와 커뮤니티가 활성화되어 있다. 많은 기능을 제공하는데, 우리는 CSV 관련 기능만 알아보도록 하자.

Pandas 가 제공하는 read_csv 는 이름 그대로 csv 파일을 읽어다가 Pandas 의 기본 데이터구조인 DataFrame 으로 만들어준다. 사용법은 정말 간단하다. 읽고자 하는 파일경로를 Pandas.read_csv(파일경로명) 으로 넘겨주면 읽어진 데이터 구조를 DataFrame 으로 리턴한다.

import pandas as pd data = pd.read_csv("./dataset.csv") data

결과는 다음과 같다.

주피터는 DataFrame 에 대하여 매우 예쁘게 그려준다. :) 판다스는 파일명이 csv 인지 무엇인지 궁금해하지 않는다. 아래와 같이 txt 로 파일 확장자가 되어 있어도 상관없이 잘 읽는다. read_csv 의 delimiter 는 구분자로 무엇을 사용할지 지정한다. 기본적으로는 쉼표를 사용하며 "공백"이나 "탭" 문자열을 가지고도 컬럼을 구분할 수 있다.

import numpy as np import pandas import matplotlib.pyplot as plt data = pandas.read_csv('dataPerson.txt',delimiter='\t') data

모든 CSV 파일에 컬럼 이름이 있는 것은 아니다. 위에서 예를 든 것처럼 연도별 자동차 정보에 대한 테이블에서 컬럼을 삭제한 다음 파일을 보자.

1997,Ford,E350,"ac, abs, moon",3000.00

1999,Chevy,"Venture ""Extended Edition""","",4900.00

1999,Chevy,"Venture ""Extended Edition, Very Large""",,5000.00

1996,Jeep,Grand Cherokee,"MUST SELL! air, moon roof, loaded",4799.00

위 파일을 판다스를 통해 읽어보면 아래와 같다. 이상하게도 인덱스에 보이지 말아야 하는 항목들이 컬럼의 인덱스로 보이고 있다.

import pandas as pd data = pd.read_csv("./dataset-no-column.csv") data

따라서 인덱스가 없는 파일을 읽을때는 다음의 옵션을 이용하여 자동으로 컬럼 인덱스의 이름을 지정하게 하거나, 직접 컬럼 이름을 지정할 수도 있다. read_csv 의 인자중 header 를 None 으로 주면 판다스는 인덱스를 자동으로 만들어낸다.

data = pd.read_csv("./dataset-no-column.csv", header=None) data

이름을 직접 주고자 하면 names 인자를 사용하면 된다.

data = pd.read_csv("./dataset-no-column.csv", names=['A', 'B', 'C', 'D']) data

판다스에서 제공하는 상세 인자는 아래와 같다.

to_csv() 함수의 인자

path_or_buf

저장할 파일의 경로와 파일명

sep

구분자 기호, default는 ','

na_rep

null값의 표현

float_format

실수형 데이터의 소수점 표현

header

True이면 header을 출력한다.

index

True이면 index를 출력한다.

line_terminator

행 구분기호로 default는 '\n'

encoding

인코딩 설정, 보통 한글은 'utf-8'로 설정

읽어진 DataFrame 구조에 대해서도 역시 많은 기능을 제공하고 있으므로 공식 홈페이지나, https://3months.tistory.com/292 등을 참고하시면 되겠다

Pandas.to_csv()


그렇다면 만들어진 데이터를 판다스를 통해 csv 로 저장하는 경우는 어떻게 해야 할까? 바로 to_csv() 를 쓰면 된다. 이 API 는 DataFrame 클래스에서 제공하고 있다. 다음과 같은 예제를 통해 알아보자. 아래 코드는 10 개의 행과 4개의 컬럼으로 이루어진 DataFrame 을 만들어 랜덤한 값으로 채우고 출력해준다.

import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(10, 4), columns=['A', 'B', 'C', 'D']) df

이렇게 만들어진 데이터 테이블에 대한 조작을 수행한후 이를 CSV 파일로 저장하기 위해 Pandas.to_csv() 를 사용한다.

df.to_csv("./result.csv")

실제 만들어진 csv 파일을 열어보면 아래와 같다.

,A,B,C,D

0,-0.12267262762054952,-1.175223853789839,-0.3708262093187317,1.972254807135157

1,-0.8437141079687297,-0.6140687114450347,-1.803237545136387,-1.1165278852009966

2,0.15846163330886018,0.7873009352686502,0.755823283711152,0.27229432404512155

3,0.6792474636098154,1.045821743404781,0.036453142713576234,-0.40498571957107254

4,-0.8083853532461803,-1.736201204944985,-0.15768283106147382,-1.8117432020195234

5,0.6442283636925334,0.9423532528307363,-2.0286884191245314,-0.8750531406721976

6,-0.6123234766300646,-0.8620832116923408,-0.6060071887405043,0.4532635653185373

7,1.6109462491352853,-0.9816397656030927,0.1291317845201808,1.088541914154095

8,0.5209148403036373,-1.0097050383026982,0.4339802451103558,0.07850650877321826

9,-1.499177754473897,0.886233992133638,-2.168266960462478,-2.2196034878438824

판다스를 이용하지 않고는?


물론 일반적인 코드로도 CSV 를 읽을 수있다. 아래와 같이 일반 파일로서 data.csv 를 읽고 한줄씩 출력하는 코드를 작성할 수 있고, 결과는 여전히 동일하게 얻을 수 있다.

import csv f = open('result.csv', 'r', encoding='utf-8') rdr = csv.reader(f) for line in rdr: print(line) f.close()

파일을 쓸때는 아래와 같은 코드를 사용할 수 있다. (출처 : 예제로 배우는 파이선 프로그래밍)

import csv f = open('output.csv', 'w', encoding='utf-8', newline='') wr = csv.writer(f) wr.writerow([1, "김정수", False]) wr.writerow([2, "박상미", True]) f.close()


'[20]개발 > [B]AI' 카테고리의 다른 글

[Python] CSV 파일 읽고 쓰기 (Pandas)  (0) 2019.02.10