4.2 데이터 입출력¶
Pandas는 데이터 파일을 읽어 데이터프레임을 만들 수 있다. 다음처럼 여러가지 포맷을 지원한다.
CSV
Excel
HTML
JSON
HDF5
SAS
STATA
SQL
여기에서는 가장 단순하지만 널리 사용되는 CSV(Comman Separated Value) 포맷 입출력에 대해 살펴본다. CSV 파일 포맷은 데이터 값이 쉽표(comma)로 구분되는 텍스트 파일이다.
%%writefile
명령¶
샘플 데이터로 사용할 CSV 파일을 %%writefile
매직(magic) 명령으로 만들어보자. 이 명령은 셀에 서술한 내용대로 텍스트 파일을 만드는 명령이다.
%%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
함수를 사용한다. 함수의 입력값으로 파일 이름을 넣는다.
pd.read_csv('sample1.csv')
c1 | c2 | c3 | |
---|---|---|---|
0 | 1 | 1.11 | one |
1 | 2 | 2.22 | two |
2 | 3 | 3.33 | three |
위에서 읽은 데이터에는 열 인덱스는 있지만 행 인덱스 정보가 없으므로 0부터 시작하는 정수 인덱스가 자동으로 추가되었다.
만약 데이터 파일에 열 인덱스 정보가 없는 경우에는 read_csv
명령의 names
인수로 설정할 수 있다.
%%writefile sample2.csv
1, 1.11, one
2, 2.22, two
3, 3.33, three
Writing sample2.csv
pd.read_csv('sample2.csv', names=['c1', 'c2', 'c3'])
c1 | c2 | c3 | |
---|---|---|---|
0 | 1 | 1.11 | one |
1 | 2 | 2.22 | two |
2 | 3 | 3.33 | three |
만약 테이블 내의 특정한 열을 행 인덱스로 지정하고 싶으면 index_col
인수를 사용한다.
pd.read_csv('sample1.csv', index_col='c1')
c2 | c3 | |
---|---|---|
c1 | ||
1 | 1.11 | one |
2 | 2.22 | two |
3 | 3.33 | three |
확장자가 CSV가 아닌 파일 즉, 데이터를 구분하는 구분자(separator)가 쉼표(comma)가 아니면 sep
인수를 써서 구분자를 사용자가 지정해준다. 만약 길이가 정해지지 않은 공백이 구분자인 경우에는 \s+
정규식(regular expression) 문자열을 사용한다.
%%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
pd.read_table('sample3.txt', sep='\s+')
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
인수를 사용한다.
%%writefile sample4.txt
파일 제목: sample4.txt
데이터 포맷의 설명:
c1, c2, c3
1, 1.11, one
2, 2.22, two
3, 3.33, three
Writing sample4.txt
pd.read_csv('sample4.txt', skiprows=[0, 1])
c1 | c2 | c3 | |
---|---|---|---|
0 | 1 | 1.11 | one |
1 | 2 | 2.22 | two |
2 | 3 | 3.33 | three |
특정한 값을 NaN으로 취급하고 싶으면 na_values
인수에 NaN 값으로 취급할 값을 넣는다.
%%writefile sample5.csv
c1, c2, c3
1, 1.11, one
2, , two
누락, 3.33, three
Writing sample5.csv
df = pd.read_csv('sample5.csv', na_values=['누락'])
df
c1 | c2 | c3 | |
---|---|---|---|
0 | 1.0 | 1.11 | one |
1 | 2.0 | two | |
2 | NaN | 3.33 | three |
CSV 파일 출력¶
지금까지와 반대로 파이썬의 데이터프레임 값을 CSV 파일로 출력하고 싶으면 to_csv
메서드를 사용한다.
df.to_csv('sample6.csv')
리눅스나 맥에서는 cat
셸 명령으로 파일의 내용을 확인할 수 있다. 윈도우에서는 type
함수를 사용한다. 느낌표(!)는 셸 함수를 사용하기 위한 아이파이썬(IPython) 매직 명령이다.
!cat sample6.csv # 윈도우에서는 !type sample6.csv 함수를 사용
,c1, c2, c3
0,1.0, 1.11, one
1,2.0, , two
2,, 3.33, three
파일을 읽을 때와 마찬가지로 출력할 때도 sep
인수로 구분자를 바꿀 수 있다.
df.to_csv('sample7.txt', sep='|')
!cat sample7.txt
|c1| c2| c3
0|1.0| 1.11| one
1|2.0| | two
2|| 3.33| three
또 na_rep
인수로 NaN 표시값을 바꿀 수도 있다.
df.to_csv('sample8.csv', na_rep='누락')
!cat sample8.csv
,c1, c2, c3
0,1.0, 1.11, one
1,2.0, , two
2,누락, 3.33, three
index
, header
인수를 지정하여 인덱스 및 헤더 출력 여부를 지정하는 것도 가능하다.
df.index = ["a", "b", "c"]
df
c1 | c2 | c3 | |
---|---|---|---|
a | 1.0 | 1.11 | one |
b | 2.0 | two | |
c | NaN | 3.33 | three |
df.to_csv('sample9.csv', index=False, header=False)
!cat sample9.csv # 윈도우에서는 !type sample6.csv 함수를 사용
1.0, 1.11, one
2.0, , two
, 3.33, three
인터넷 상의 CSV 파일 입력¶
웹상에는 다양한 데이터 파일이 CSV 파일 형태로 제공된다. read_csv
명령 사용시 파일 패스 대신 URL을 지정하면 Pandas가 직접 해당 파일을 다운로드하여 읽어들인다. 다음은 저자의 github 웹사이트에 저장되어 있는 데이터 파일을 원격으로 읽는 명령이다.
df = pd.read_csv("https://raw.githubusercontent.com/datascienceschool/docker_rpython/master/data/titanic.csv")
이 데이터프레임은 실제로 데이터 갯수, 즉 행(row)의 수가 890개가 넘는 대량의 데이터이다. 이렇게 데이터의 수가 많을 경우, 데이터프레임의 표현(representation)은 데이터 앞, 뒤의 일부분만 보여준다. 보여줄 행의 수는 display.max_rows
옵션으로 정할 수 있다.
pd.set_option("display.max_rows", 20) # 앞뒤로 모두 20행만 보여준다.
df
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 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
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
메서드를 이용한다. 메서드 인수로 출력할 행의 수를 넣을 수도 있다.
df.head()
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 |
df.tail(2)
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 패키지를 사용한다.
import datetime
dt_start = datetime.datetime(2015, 1, 1)
dt_end = "2016, 6, 30"
data_source
인수로 데이터를 읽어올 웹 사이트를 지정한다. 데이터의 코드는 웹 사이트에서 검색하여 알아내야 한다. 다음은 FRED 데이터베이스에서 미국 국가총생산(GDP), 모든 항목을 포함한 소비자 가격 지수(CPIAUCSL), 식료품 및 연로를 제외한 소비자 가격 지수(CPILFESL)를 가져오는 예이다. 웹사이트에서 자세한 데이터에 대한 세부적인 사항이나 값을 확인할 수 있다.
import pandas_datareader as pdr
gdp = pdr.get_data_fred('GDP', dt_start, dt_end)
gdp.tail()
GDP | |
---|---|
DATE | |
2015-04-01 | 18223.577 |
2015-07-01 | 18347.425 |
2015-10-01 | 18378.803 |
2016-01-01 | 18470.156 |
2016-04-01 | 18656.207 |
데이터 코드에 리스트를 넣으면 여러개의 데이터를 동시에 가져온다.
inflation = pdr.get_data_fred(["CPIAUCSL", "CPILFESL"], dt_start, dt_end)
inflation.tail()
CPIAUCSL | CPILFESL | |
---|---|---|
DATE | ||
2016-02-01 | 237.514 | 245.644 |
2016-03-01 | 237.990 | 245.964 |
2016-04-01 | 238.835 | 246.467 |
2016-05-01 | 239.440 | 247.036 |
2016-06-01 | 240.144 | 247.435 |