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

데이터 입출력

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

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

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

%%writefile 명령

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

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

CSV 파일 입력

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

In:
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:
%%writefile sample2.csv
1, 1.11, one
2, 2.22, two
3, 3.33, three
Writing sample2.csv
In:
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:
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:
%%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:
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:
%%writefile sample4.txt
파일 제목: sample4.txt
데이터 포맷의 설명: 
c1, c2, c3
1, 1.11, one
2, 2.22, two
3, 3.33, three
Writing sample4.txt
In:
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:
%%writefile sample5.csv
c1, c2, c3
1, 1.11, one
2,, two
누락, 3.33, three
Writing sample5.csv
In:
df = pd.read_csv('sample5.csv', na_values=['누락'])
df
Out:
c1 c2 c3
0 1.0 1.11 one
1 2.0 NaN two
2 NaN 3.33 three

CSV 파일 출력

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

In:
df.to_csv('sample6.csv')

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

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

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

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

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

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

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

In:
df.index = ["a", "b", "c"]
df
Out:
c1 c2 c3
a 1.0 1.11 one
b 2.0 NaN two
c NaN 3.33 three
In:
df.to_csv('sample9.csv', index=False, header=False)
In:
!cat sample9.csv
1.0,1.11, one
2.0,, two
,3.33, three

인터넷 상의 CSV 파일 입력

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

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

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

In:
df
Out:
survived pclass sex age sibsp parch fare embarked class who adult_male deck embark_town alive alone
0 0 3 male 22.0 1 0 7.2500 S Third man True NaN Southampton no False
1 1 1 female 38.0 1 0 71.2833 C First woman False C Cherbourg yes False
2 1 3 female 26.0 0 0 7.9250 S Third woman False NaN Southampton yes True
3 1 1 female 35.0 1 0 53.1000 S First woman False C Southampton yes False
4 0 3 male 35.0 0 0 8.0500 S Third man True NaN Southampton no True
5 0 3 male NaN 0 0 8.4583 Q Third man True NaN Queenstown no True
6 0 1 male 54.0 0 0 51.8625 S First man True E Southampton no True
7 0 3 male 2.0 3 1 21.0750 S Third child False NaN Southampton no False
8 1 3 female 27.0 0 2 11.1333 S Third woman False NaN Southampton yes False
9 1 2 female 14.0 1 0 30.0708 C Second child False NaN Cherbourg yes False
10 1 3 female 4.0 1 1 16.7000 S Third child False G Southampton yes False
11 1 1 female 58.0 0 0 26.5500 S First woman False C Southampton yes True
12 0 3 male 20.0 0 0 8.0500 S Third man True NaN Southampton no True
13 0 3 male 39.0 1 5 31.2750 S Third man True NaN Southampton no False
14 0 3 female 14.0 0 0 7.8542 S Third child False NaN Southampton no True
15 1 2 female 55.0 0 0 16.0000 S Second woman False NaN Southampton yes True
16 0 3 male 2.0 4 1 29.1250 Q Third child False NaN Queenstown no False
17 1 2 male NaN 0 0 13.0000 S Second man True NaN Southampton yes True
18 0 3 female 31.0 1 0 18.0000 S Third woman False NaN Southampton no False
19 1 3 female NaN 0 0 7.2250 C Third woman False NaN Cherbourg yes True
20 0 2 male 35.0 0 0 26.0000 S Second man True NaN Southampton no True
21 1 2 male 34.0 0 0 13.0000 S Second man True D Southampton yes True
22 1 3 female 15.0 0 0 8.0292 Q Third child False NaN Queenstown yes True
23 1 1 male 28.0 0 0 35.5000 S First man True A Southampton yes True
24 0 3 female 8.0 3 1 21.0750 S Third child False NaN Southampton no False
25 1 3 female 38.0 1 5 31.3875 S Third woman False NaN Southampton yes False
26 0 3 male NaN 0 0 7.2250 C Third man True NaN Cherbourg no True
27 0 1 male 19.0 3 2 263.0000 S First man True C Southampton no False
28 1 3 female NaN 0 0 7.8792 Q Third woman False NaN Queenstown yes True
29 0 3 male NaN 0 0 7.8958 S Third man True NaN Southampton no True
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
861 0 2 male 21.0 1 0 11.5000 S Second man True NaN Southampton no False
862 1 1 female 48.0 0 0 25.9292 S First woman False D Southampton yes True
863 0 3 female NaN 8 2 69.5500 S Third woman False NaN Southampton no False
864 0 2 male 24.0 0 0 13.0000 S Second man True NaN Southampton no True
865 1 2 female 42.0 0 0 13.0000 S Second woman False NaN Southampton yes True
866 1 2 female 27.0 1 0 13.8583 C Second woman False NaN Cherbourg yes False
867 0 1 male 31.0 0 0 50.4958 S First man True A Southampton no True
868 0 3 male NaN 0 0 9.5000 S Third man True NaN Southampton no True
869 1 3 male 4.0 1 1 11.1333 S Third child False NaN Southampton yes False
870 0 3 male 26.0 0 0 7.8958 S Third man True NaN Southampton no True
871 1 1 female 47.0 1 1 52.5542 S First woman False D Southampton yes False
872 0 1 male 33.0 0 0 5.0000 S First man True B Southampton no True
873 0 3 male 47.0 0 0 9.0000 S Third man True NaN Southampton no True
874 1 2 female 28.0 1 0 24.0000 C Second woman False NaN Cherbourg yes False
875 1 3 female 15.0 0 0 7.2250 C Third child False NaN Cherbourg yes True
876 0 3 male 20.0 0 0 9.8458 S Third man True NaN Southampton no True
877 0 3 male 19.0 0 0 7.8958 S Third man True NaN Southampton no True
878 0 3 male NaN 0 0 7.8958 S Third man True NaN Southampton no True
879 1 1 female 56.0 0 1 83.1583 C First woman False C Cherbourg yes False
880 1 2 female 25.0 0 1 26.0000 S Second woman False NaN Southampton yes False
881 0 3 male 33.0 0 0 7.8958 S Third man True NaN Southampton no True
882 0 3 female 22.0 0 0 10.5167 S Third woman False NaN Southampton no True
883 0 2 male 28.0 0 0 10.5000 S Second man True NaN Southampton no True
884 0 3 male 25.0 0 0 7.0500 S Third man True NaN Southampton no True
885 0 3 female 39.0 0 5 29.1250 Q Third woman False NaN Queenstown no False
886 0 2 male 27.0 0 0 13.0000 S Second man True NaN Southampton no True
887 1 1 female 19.0 0 0 30.0000 S First woman False B Southampton yes True
888 0 3 female NaN 1 2 23.4500 S Third woman False NaN Southampton no False
889 1 1 male 26.0 0 0 30.0000 C First man True C Cherbourg yes True
890 0 3 male 32.0 0 0 7.7500 Q Third man True NaN Queenstown no True

891 rows × 15 columns

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

In:
df.head()
Out:
survived pclass sex age sibsp parch fare embarked class who adult_male deck embark_town alive alone
0 0 3 male 22.0 1 0 7.2500 S Third man True NaN Southampton no False
1 1 1 female 38.0 1 0 71.2833 C First woman False C Cherbourg yes False
2 1 3 female 26.0 0 0 7.9250 S Third woman False NaN Southampton yes True
3 1 1 female 35.0 1 0 53.1000 S First woman False C Southampton yes False
4 0 3 male 35.0 0 0 8.0500 S Third man True NaN Southampton no True
In:
df.tail(2)
Out:
survived pclass sex age sibsp parch fare embarked class who adult_male deck embark_town alive alone
889 1 1 male 26.0 0 0 30.00 C First man True C Cherbourg yes True
890 0 3 male 32.0 0 0 7.75 Q Third man True NaN Queenstown no True

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

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

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

In:
from pandas_datareader.data import DataReader

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

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

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

In:
gdp = DataReader("GDP", "fred", dt_start, dt_end)
gdp.tail()
Out:
GDP
DATE
2015-04-01 18093.224
2015-07-01 18227.689
2015-10-01 18287.226
2016-01-01 18325.187
2016-04-01 18538.039

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

In:
inflation = DataReader(["CPIAUCSL", "CPILFESL"], "fred", dt_start, dt_end)
inflation.tail()
Out:
CPIAUCSL CPILFESL
DATE
2016-02-01 237.808 245.845
2016-03-01 238.078 246.062
2016-04-01 238.908 246.517
2016-05-01 239.362 247.026
2016-06-01 239.842 247.389

질문/덧글

오타수정 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는 아직 사용해보지 않았습니다.