다운로드
작성자: admin 작성일시: 2016-07-08 22:27:40 조회수: 27946 다운로드: 405
카테고리: Python 태그목록:

데이터 입출력

Pandas는 데이터 파일을 읽어 데이터프레임을 만들 수 있다. 다음처럼 여러가지 포맷을 지원한다.

  • CSV
  • Excel
  • HTML
  • JSON
  • HDF5
  • SAS
  • STATA
  • SQL

여기에서는 가장 단순하지만 널리 사용되는 CSV(Comman Separated Value) 포맷 입출력에 대해 살펴본다. CSV 파일 포맷은 데이터 값이 쉽표(comma)로 구분되는 텍스트 파일이다.

%%writefile 명령

샘플 데이터로 사용할 CSV 파일을 %%writefile 매직(magic) 명령으로 만들어보자. 이 명령은 셀에 서술한 내용대로 텍스트 파일을 만드는 명령이다.

In [2]:
%%writefile sample1.csv
c1, c2, c3
1, 1.11, one
2, 2.22, two
3, 3.33, three
Writing sample1.csv

CSV 파일 입력

CSV 파일로부터 데이터를 읽어 데이터프레임을 만들 때는 pandas.read_csv() 명령을 사용한다.

In [3]:
pd.read_csv('sample1.csv')
Out:
c1 c2 c3
0 1 1.11 one
1 2 2.22 two
2 3 3.33 three

위에서 읽은 데이터에는 열 인덱스는 있지만 행 인덱스 정보가 없으므로 0부터 시작하는 정수 인덱스가 자동으로 추가되었다. 만약, 위의 경우와 달리, 데이터 파일에 열 인덱스 정보가 없는 경우에는 read_csv 명령의 names 인수로 설정할 수 있다.

In [4]:
%%writefile sample2.csv
1, 1.11, one
2, 2.22, two
3, 3.33, three
Writing sample2.csv
In [5]:
pd.read_csv('sample2.csv', names=['c1', 'c2', 'c3'])
Out:
c1 c2 c3
0 1 1.11 one
1 2 2.22 two
2 3 3.33 three

만약 테이블 내의 특정한 열을 행 인덱스로 지정하고 싶으면 index_col 인수를 사용한다.

In [6]:
pd.read_csv('sample1.csv', index_col='c1')
Out:
c2 c3
c1
1 1.11 one
2 2.22 two
3 3.33 three

확장자가 CSV가 아닌 파일 즉, 데이터를 구분하는 구분자(separator)가 쉼표(comma)가 아니면 sep 인수를 써서 구분자를 사용자가 지정해준다. 만약 구분자가 길이가 정해지지 않은 공백인 경우에는 \s+라는 정규식(regular expression) 문자열을 사용한다.

In [7]:
%%writefile sample3.txt
c1        c2        c3        c4
0.179181 -1.538472  1.347553  0.43381
1.024209  0.087307 -1.281997  0.49265
0.417899 -2.002308  0.255245 -1.10515
Writing sample3.txt
In [8]:
pd.read_table('sample3.txt', sep='\s+')
Out:
c1 c2 c3 c4
0 0.179181 -1.538472 1.347553 0.43381
1 1.024209 0.087307 -1.281997 0.49265
2 0.417899 -2.002308 0.255245 -1.10515

만약 자료 파일 중에 건너 뛰어야 할 행이 있으면 skiprows 인수를 사용한다.

In [9]:
%%writefile sample4.txt
파일 제목: sample4.txt
데이터 포맷의 설명:
c1, c2, c3
1, 1.11, one
2, 2.22, two
3, 3.33, three
Writing sample4.txt
In [10]:
pd.read_csv('sample4.txt', skiprows=[0, 1])
Out:
c1 c2 c3
0 1 1.11 one
1 2 2.22 two
2 3 3.33 three

특정한 값을 NaN으로 취급하고 싶으면 na_values 인수에 NaN 값으로 취급할 값을 넣는다.

In [11]:
%%writefile sample5.csv
c1, c2, c3
1, 1.11, one
2, , two
누락, 3.33, three
Writing sample5.csv
In [12]:
df = pd.read_csv('sample5.csv', na_values=['누락'])
df
Out:
c1 c2 c3
0 1.0 1.11 one
1 2.0 two
2 NaN 3.33 three

CSV 파일 출력

지금까지와 반대로 파이썬의 데이터프레임 값을 CSV 파일로 출력하고 싶으면 to_csv() 메서드를 사용한다.

In [13]:
df.to_csv('sample6.csv')

리눅스나 맥에서는 cat 셸 명령으로 파일의 내용을 확인할 수 있다. 윈도우에서는 type 명령을 사용한다. 느낌표(!)는 셸 명령을 사용하기 위한 IPython 매직 명령이다.

In [14]:
!cat sample6.csv  # 윈도우에서는 !type sample6.csv 명령을 사용
,c1, c2, c3
0,1.0, 1.11, one
1,2.0, , two
2,, 3.33, three

파일을 읽을 때와 마찬가지로 출력할 때도 sep 인수로 구분자를 바꿀 수 있다.

In [15]:
df.to_csv('sample7.txt', sep='|')
In [16]:
!cat sample7.txt
|c1| c2| c3
0|1.0| 1.11| one
1|2.0| | two
2|| 3.33| three

na_rep 인수로 NaN 표시값을 바꿀 수도 있다.

In [17]:
df.to_csv('sample8.csv', na_rep='누락')
In [18]:
!cat sample8.csv
,c1, c2, c3
0,1.0, 1.11, one
1,2.0, , two
2,누락, 3.33, three

index, header 인수를 지정하여 인덱스 및 헤더 출력 여부를 지정하는 것도 가능하다.

In [19]:
df.index = ["a", "b", "c"]
df
Out:
c1 c2 c3
a 1.0 1.11 one
b 2.0 two
c NaN 3.33 three
In [20]:
df.to_csv('sample9.csv', index=False, header=False)
In [21]:
!cat sample9.csv  # 윈도우에서는 !type sample6.csv 명령을 사용
1.0, 1.11, one
2.0, , two
, 3.33, three

인터넷 상의 CSV 파일 입력

웹상에는 다양한 데이터 파일이 CSV 파일 형태로 제공된다. read_csv 명령 사용시 파일 패스 대신 URL을 지정하면 Pandas가 직접 해당 파일을 다운로드하여 읽어들인다. 다음은 저자의 github 웹사이트에 저장되어 있는 데이터 파일을 원격으로 읽는 명령이다.

In [22]:
df = pd.read_csv("https://raw.githubusercontent.com/datascienceschool/docker_rpython/master/data/titanic.csv")

이 데이터프레임은 실제로 데이터 갯수, 즉 행(row)의 수가 890개가 넘는 대량의 데이터이다. 이렇게 데이터의 수가 많을 경우, 데이터프레임의 표현(representation)은 데이터 앞, 뒤의 일부분만 보여준다. 보여줄 행의 수는 display.max_rows 옵션으로 정할 수 있다.

In [23]:
pd.set_option("display.max_rows", 20)  # 앞뒤로 모두 20행만 보여준다.
df
Out:
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
5 6 0 3 Moran, Mr. James male NaN 0 0 330877 8.4583 NaN Q
6 7 0 1 McCarthy, Mr. Timothy J male 54.0 0 0 17463 51.8625 E46 S
7 8 0 3 Palsson, Master. Gosta Leonard male 2.0 3 1 349909 21.0750 NaN S
8 9 1 3 Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg) female 27.0 0 2 347742 11.1333 NaN S
9 10 1 2 Nasser, Mrs. Nicholas (Adele Achem) female 14.0 1 0 237736 30.0708 NaN C
... ... ... ... ... ... ... ... ... ... ... ... ...
881 882 0 3 Markun, Mr. Johann male 33.0 0 0 349257 7.8958 NaN S
882 883 0 3 Dahlberg, Miss. Gerda Ulrika female 22.0 0 0 7552 10.5167 NaN S
883 884 0 2 Banfield, Mr. Frederick James male 28.0 0 0 C.A./SOTON 34068 10.5000 NaN S
884 885 0 3 Sutehall, Mr. Henry Jr male 25.0 0 0 SOTON/OQ 392076 7.0500 NaN S
885 886 0 3 Rice, Mrs. William (Margaret Norton) female 39.0 0 5 382652 29.1250 NaN Q
886 887 0 2 Montvila, Rev. Juozas male 27.0 0 0 211536 13.0000 NaN S
887 888 1 1 Graham, Miss. Margaret Edith female 19.0 0 0 112053 30.0000 B42 S
888 889 0 3 Johnston, Miss. Catherine Helen "Carrie" female NaN 1 2 W./C. 6607 23.4500 NaN S
889 890 1 1 Behr, Mr. Karl Howell male 26.0 0 0 111369 30.0000 C148 C
890 891 0 3 Dooley, Mr. Patrick male 32.0 0 0 370376 7.7500 NaN Q

891 rows × 12 columns

만약 앞이나 뒤의 특정 갯수만 보고 싶다면 head 메서드나 tail 메서드를 이용한다. 메서드 인수로 출력할 행의 수를 넣을 수도 있다.

In [24]:
df.head()
Out:
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
In [25]:
df.tail(2)
Out:
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
889 890 1 1 Behr, Mr. Karl Howell male 26.0 0 0 111369 30.00 C148 C
890 891 0 3 Dooley, Mr. Patrick male 32.0 0 0 370376 7.75 NaN Q

인터넷 상의 데이터 베이스 자료 입력

pandas_datareader 패키지의 DataReader 을 사용하면 일부 인터넷 사이트의 자료를 바로 pandas로 읽어들일 수 있다. pandas_datareader 패키지는 판다스와 별도로 설치해야 한다. 다음은 pandas_datareader 패키지가 제공하는 인터넷 사이트의 예이다. 일부 인터넷 사이트는 유료이므로 별도의 가입절차를 거쳐야 한다.

  • FRED
  • Fama/French
  • World Bank
  • OECD
  • Eurostat
  • EDGAR Index
  • TSP Fund Data
  • Oanda currency historical rate
  • Nasdaq Trader Symbol Definitions

자세한 내용은 다음 웹사이트를 참조한다.

날짜는 datetime 패키지를 사용하여 지정해도 되고 문자열을 바로 사용해도 된다. (이때는 내부적으로 dateutil 패키지를 사용한다.

In [26]:
import datetime
dt_start = datetime.datetime(2015, 1, 1)
dt_end = "2016, 6, 30"

data_source 인수로 데이터를 읽어올 웹 사이트를 지정한다. 데이터의 코드는 웹 사이트에서 검색하여 알아내야 한다. 다음은 FRED 데이터베이스에서 미국 국가총생산(GDP), 모든 항목을 포함한 소비자 가격 지수(CPIAUCSL), 식료품 및 연로를 제외한 소비자 가격 지수(CPILFESL)를 가져오는 예이다. 웹사이트에서 자세한 데이터에 대한 세부적인 사항이나 값을 확인할 수 있다.

In [27]:
import pandas_datareader as pdr

gdp = pdr.get_data_fred('GDP', dt_start, dt_end)
gdp.tail()
Out:
GDP
DATE
2015-04-01 18221.299
2015-07-01 18331.093
2015-10-01 18354.372
2016-01-01 18409.130
2016-04-01 18640.732

데이터 코드에 리스트를 넣으면 여러개의 데이터를 동시에 가져온다.

In [28]:
inflation = pdr.get_data_fred(["CPIAUCSL", "CPILFESL"], dt_start, dt_end)
inflation.tail()
Out:
CPIAUCSL CPILFESL
DATE
2016-02-01 237.532 245.689
2016-03-01 238.022 246.004
2016-04-01 238.843 246.487
2016-05-01 239.439 247.031
2016-06-01 240.074 247.436

질문/덧글

오타수정 531c*** 2016년 7월 10일 5:00 오후

pandas.from_csv(): csv file -> DataFrame

이 부분에서
from_csv()가 아니라 read_csv()인 것 같습니다.

답변: 오타수정 관리자 2016년 7월 10일 7:01 오후

오타가 아니고 `from_csv` 와 `read_csv` 명령 두 개 모두 존재합니다.

감사합니다. 531c*** 2016년 7월 12일 2:44 오후

감사합니다.

pandas / zipline /pipeline park*** 2016년 8월 10일 11:01 오전

pandas datareader 로 자료 받기
zipline을 받기
또 quantopian 의 다른 pipeline으로 받기를 하면

뭐가 다른가요 ?

quantopian package는 데이터 클리닝을 알아서 해 주나요 ?

답변: pandas / zipline /pipeline 관리자 2016년 8월 10일 7:25 오후

zipline의 load_xxx 명령어 들은 내부적으로 pandas를 이용합니다.
다만 timezone 정보를 추가하거나 adj.close가 없는 경우 생성합니다.
https://github.com/quantopian/zipline/blob/master/zipline/data/loader.py
pipeline API는 아직 사용해보지 않았습니다.