In [1]:
from __future__ import print_function, division
오늘 다루는 내용은 pandas 모듈의 소개 정도로 이해하고 넘어갈 것을 권장한다.
아래 내용은 엑셀의 스프레드시트지에 담긴 데이터를 분석하여 평균 등을 어떻게 구하는가를 알고 있다면 어렵지 않게 이해할 수 있는 내용이다. 즉, 넘파이의 어레이에 대한 기초지식과 엑셀에 대한 기초지식을 활용하면 내용을 기본적으로 이해할 수 있을 것이다.
좀 더 자세한 설명이 요구된다면 아래 사이트의 설명을 미리 읽으면 좋다(5.2절 내용까지면 충분함). 하지만, 아래 내용을 엑셀의 기능과 비교하면서 먼저 주욱 훑어 볼 것을 권장한다.
http://sinpong.tistory.com/category/Python%20for%20data%20analysis
미국에서 거래되는 담배(식물)의 도매가격 데이터를 분석하여, 거래된 도매가의 평균을 구한다.
평균에 대한 보다 자세한 설명은 첨부된 강의노트 참조: GongSu21-Averages.pdf
In [2]:
import numpy as np
import pandas as pd
from datetime import datetime as dt
from scipy import stats
오늘 사용할 데이터는 다음과 같다.
아래 그림은 미국의 주별 담배(식물) 판매 데이터를 담은 Weed_Price.csv 파일를 엑셀로 읽었을 때의 일부를 보여준다. 실제 데이터량은 22899개이며, 아래 그림에는 5개의 데이터만을 보여주고 있다.
|
언급한 세 개의 csv 파일을 pandas의 read_csv 함수를 이용하여 불러들이자.
주의: Weed_Price.csv 파일을 불러들일 때, parse_dates라는 키워드 인자가 사용되었다.
In [3]:
prices_pd = pd.read_csv("data/Weed_Price.csv", parse_dates=[-1])
read_csv 함수의 리턴값은 DataFrame 이라는 자료형이다.
In [4]:
type(prices_pd)
Out[4]:
자세한 설명은 다음 시간에 추가될 것임. 우선은 아래 사이트를 참조할 수 있다는 정도만 언급함. (5.2절 내용까지면 충분함)
http://sinpong.tistory.com/category/Python%20for%20data%20analysis
불러 들인 Weed_Price.csv 파일의 상위 다섯 줄을 확인해보면, 앞서 엑셀파일 그림에서 본 내용과 일치한다. 다만, 행과 열의 목록이 조금 다를 뿐이다.
하지만 read_csv 파일은 좀 다르게 불러 들인다.
데이터 파일의 상위 몇 줄을 불러들이기 위해서는 DataFrame 자료형의 head 메소드를 활용한다. 인자값을 주지 않으면 상위 5줄을 보여준다.
In [5]:
prices_pd.head()
Out[5]:
인자를 주면 원하는 만큼 보여준다.
In [6]:
prices_pd.head(10)
Out[6]:
파일이 매우 많은 수의 데이터를 포함하고 있을 경우, 맨 뒷쪽 부분을 확인하고 싶으면 tail 메소드를 활용한다. 사용법은 head 메소드와 동일하다.
아래 명령어를 통해 Weed_Price.csv 파일에 22899개의 데이터가 저장되어 있음을 확인할 수 있다.
In [7]:
prices_pd.tail()
Out[7]:
DataFrame 자료형의 dtypes 속성을 이용하면 열별 목록에 사용된 자료형을 확인할 수 있다.
Weed_Price.csv 파일을 읽어 들인 prices_pd 변수에 저장된 DataFrame 값의 열별 목록에 사용된 자료형을 보여준다.
주의:
In [8]:
prices_pd.dtypes
Out[8]:
In [9]:
prices_pd.sort_values(['State', 'date'], inplace=True)
In [10]:
prices_pd.fillna(method='ffill', inplace=True)
정렬된 데이터의 첫 부분은 아래와 같이 알라바마(Alabama) 주의 데이터만 날짜별로 순서대로 보인다.
In [11]:
prices_pd.head()
Out[11]:
정렬된 데이터의 끝 부분은 아래와 같이 요밍(Wyoming) 주의 데이터만 날짜별로 순서대로 보인다. 이제 결측치가 더 이상 존재하지 않는다.
In [12]:
prices_pd.tail()
Out[12]:
먼저 마스크 인덱스를 이용하여 캘리포니아 주의 데이터만 추출해야 한다.
In [13]:
california_pd = prices_pd[prices_pd.State == "California"].copy(True)
캘리포니아 주에서 거래된 첫 5개의 데이터를 확인해보자.
In [14]:
california_pd.head(20)
Out[14]:
HighQ 열 목록에 있는 값들의 총합을 구해보자.
주의: sum()
메소드 활용을 기억한다.
In [15]:
ca_sum = california_pd['HighQ'].sum()
ca_sum
Out[15]:
HighQ 열 목록에 있는 값들의 개수를 확인해보자.
주의: count()
메소드 활용을 기억한다.
In [16]:
ca_count = california_pd['HighQ'].count()
ca_count
Out[16]:
이제 캘리포니아 주에서 거래된 HighQ의 담배가격의 평균값을 구할 수 있다.
In [17]:
# 캘리포니아 주에서 거래된 상품(HighQ) 담배(식물) 도매가의 평균값
ca_mean = ca_sum / ca_count
ca_mean
Out[17]:
여기서는 데이터의 크기가 449로 홀수이다.
In [18]:
ca_count
Out[18]:
따라서 중앙값은 $\frac{\text{ca_count}-1}{2}$번째에 위치한 값이다.
주의: 인덱스는 0부터 출발한다. 따라서 중앙값이 하나 앞으로 당겨진다.
In [19]:
ca_highq_pd = california_pd.sort_values(['HighQ'])
ca_highq_pd.head()
Out[19]:
인덱스 로케이션 함수인 iloc
함수를 활용한다.
주의: iloc
메소드는 인덱스 번호를 사용한다.
위 표에서 보여주는 인덱스 번호는 Weed_Price.csv 파일을 처음 불러왔을 때 사용된 인덱스 번호이다.
하지만 ca_high_pd 에서는 참고사항으로 사용될 뿐이며, iloc
함수에 인자로 들어가는 인덱스는 다시 0부터 세는 것으로 시작한다.
따라서 아래 코드처럼 기존의 참고용 인덱스를 사용하면 옳은 답을 구할 수 없다.
In [20]:
# 캘리포니아에서 거래된 상품(HighQ) 담배(식물) 도매가의 중앙값
ca_median = ca_highq_pd.HighQ.iloc[int((ca_count-1)/ 2)]
ca_median
Out[20]:
In [21]:
# 캘리포니아 주에서 가장 빈번하게 거래된 상품(HighQ) 담배(식물)의 도매가
ca_mode = ca_highq_pd.HighQ.value_counts().index[0]
ca_mode
Out[21]:
In [22]:
california_pd.mean()
Out[22]:
In [23]:
california_pd.mean().HighQ
Out[23]:
In [24]:
california_pd.median()
Out[24]:
In [25]:
california_pd.mode()
Out[25]:
In [26]:
california_pd.mode().HighQ
Out[26]:
In [27]:
california_pd.HighQ.mean()
Out[27]:
In [28]:
california_pd.HighQ.median()
Out[28]:
In [29]:
california_pd.HighQ.mode()
Out[29]:
In [30]:
sum = 0
count = 0
for index in np.arange(len(california_pd)):
if california_pd.iloc[index]['date'].year == 2014:
sum += california_pd.iloc[index]['HighQ']
count += 1
sum/count
Out[30]:
In [31]:
years = np.arange(2013, 2016)
year_starts = [0]
for yr in years:
for index in np.arange(year_starts[-1], len(california_pd)):
if california_pd.iloc[index]['date'].year == yr:
continue
else:
year_starts.append(index)
break
year_starts
Out[31]:
year_starts
에 담긴 숫자들의 의미는 다음과 같다.
0번줄부터 2013년도 거래가 표시된다.
5번줄부터 2014년도 거래가 표시된다.
369번줄부터 2015년도 거래가 표시된다.
In [32]:
california_pd.iloc[4]
Out[32]:
In [33]:
california_pd.iloc[5]
Out[33]:
In [34]:
california_pd.iloc[368]
Out[34]:
In [35]:
california_pd.iloc[369]
Out[35]: