티스토리 뷰

반응형


.Setting

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
 
import numpy as np
 
from pandas import Series, DataFrame
 
from numpy import nan as NA
 
import matplotlib.pyplot as plt
 
%matplotlib qt
cs

--


.시계열 데이터

1
2
3
4
5
from datetime import datetime  # datetime 모듈 안에 datetime 함수
 
now = datetime.now()  # sysdate in oracle, Sysdate in R
 
now.year, now.month, now.day
cs

--


.날짜 생성

1
datetime(2019,2,20) - datetime(1994,7,31)
cs

--


. timedelta

1
2
3
4
5
6
7
from datetime import timedelta
 
# datetime.now() + 1  # R과 다르게 날짜와 정수 연산 불가 (서로 다른 데이터 타입)
 
# unsupported operand type(s) for +: 'datetime.datetime' and 'int'
 
datetime.now() + timedelta(1# 정수를 '일'형식으로 변환
cs

--


.strftime

# strftime : format 변경  (날짜 -> 문자열), 벡터연산 불가

1
2
3
4
5
now = datetime.now()
 
now.strftime('%Y-%m-%d')
 
type(now.strftime('%Y-%m-%d'))  # 날짜 -> 문자열
cs

--


.strptime

# strptime : pasing  (문자열 -> 날짜), 벡터연산 불가

1
2
3
4
5
6
7
8
9
day = '2019-02-20'
 
datetime.strptime(a1, '%Y-%m-%d')  # 문자열 -> 날짜
 
datetime.strptime(a1, '%Y-%m-%d').month
 
datetime.strptime(a1, '%Y-%m-%d').day
 
datetime.strptime(a1, '%Y-%m-%d').strftime('%A')  # 요일
cs


1
2
3
4
5
6
7
l1 = ['2019-01-01''2019-01-02']  
 
# datetime.strptime(l1, '%Y-%m-%d')  # 벡터연산 불가 
 
f1 = lambda x : datetime.strptime(x, '%Y-%m-%d')
 
list(map(f1,l1))
cs

--


.parser.parse

### parser.parse ; 참고로만 

# 파싱 없이도  변환 

1
2
3
4
5
6
7
from dateutil.parser import parse
day = '2019-02-20'
parse(day)
 
day2 = '02/05/2019'
parse(day2)  # dayfirst = False
parse(day2, dayfirst = True)
cs

--


.to_datetime

### to_datetime 함수 : 벡터연산이 가능한 날짜 변환

1
2
3
4
5
6
7
8
9
l1 = ['2019-01-01''2019-01-02'
 
pd.to_datetime(l1)
 
l2 = ['01.01-2019''01.02-2019'
 
# pd.to_datetime(l2)  # 자동 파싱 기능이 부족 
 
pd.to_datetime(l2, format = '%m.%d-%Y')  # 기본 날짜 형식으로 출력 
cs


# NaT : 날짜의 null 값

--


.resample

# resample 메서드

# 일정한 빈도수(일,주,월)로 리샘플 => 결합, 조인 연산을 위해 사용

1
2
3
4
5
6
7
8
9
10
11
12
# pd.data_range 연속적인 날짜 출력
pd.date_range('2019/01/01''2019/12/31')  # freq='D' 일 단위
pd.date_range('2019/01/01''2019/12/31', freq='W')   # 주 단위 (W-SUN 매주 일요일)
pd.date_range('2019/01/01''2019/12/31', freq='W-WED')   # 주 단위 (W-SUN 매주 수요일)
 
pd.date_range(start='2019/01/01', periods=5)  # start ~ 연속적인 5일 
pd.date_range('2019/01/01', periods=5, freq='W-SAT')  # start ~ 연속적인 토요일 5일 
 
ind1 = pd.date_range('2019/01/01', periods=5, freq='W-SAT')  
s1 = Series(np.arange(5), index=ind1)
s1.resample('D')  # 이제 결과를 저장만 하고 출력을 해주지 않음. group 함수와 사용해야 함
s1.resample('D').count()
cs

--


.pd.data_range

# pd.data_range 연속적인 날짜 출력

1
2
3
4
5
6
7
8
9
10
11
pd.date_range('2019/01/01''2019/12/31')  # freq='D' 일 단위
pd.date_range('2019/01/01''2019/12/31', freq='W')   # 주 단위 (W-SUN 매주 일요일)
pd.date_range('2019/01/01''2019/12/31', freq='W-WED')   # 주 단위 (W-SUN 매주 수요일)
 
pd.date_range(start='2019/01/01', periods=5)  # start ~ 연속적인 5일 
pd.date_range('2019/01/01', periods=5, freq='W-SAT')  # start ~ 연속적인 토요일 5일 
 
ind1 = pd.date_range('2019/01/01', periods=5, freq='W-SAT')  
s1 = Series(np.arange(5), index=ind1)
s1.resample('D')  # 이제 결과를 저장만 하고 출력을 해주지 않음. group 함수와 사용해야 함
s1.resample('D').count()
cs

--

# 각 날짜의 빈도  20p

from pandas.tseries.offsets import Hour, Minute

# B : 중요한 표현식. 주말, 공휴일 제외

# MB : 월 영업 마감일 

# WOM-2MON : 몇 째주 무슨 요일


# 리샘플링

# 다운샘플링 : 높은 freq -> 낮은 freq (그룹화) (일-주-월)

# 업샘플링  : 낮은 freq -> 높은 freq (개별화) (월-주-일)


1
2
3
4
5
6
emp = pd.read_csv('emp.csv', encoding='cp949')
emp.dtypes
emp.index = pd.to_datetime(emp['HIREDATE']) # 기본 format이므로 지정 필요 없음
emp['1981-09']  # datetime index 
 
pd.read_csv('emp.csv', encoding='cp949', parse_dates= [4]) # 데이터 불러올 때 날짜 parsing
cs



#. Q1

# 1. delivery.csv 파일을 읽고

1
2
delv = pd.read_csv('delivery.csv', encoding='cp949')
s1 = delv.groupby('일자')['통화건수'].sum()
cs


# 1) 일자별 총 통화건수와 전일대비 증가량을 구하여라

1
2
s2 = s1.shift(1)
(s1 - s2) / s2 * 100
cs


# 2) 요일별로 각 업종별 통화건수를 확인하고 막대그래프로 표현하여라

1
2
3
4
5
6
7
8
9
10
delv.dtypes
delv['일자'= pd.to_datetime(delv['일자'], format='%Y%m%d')
 
delv['요일'= delv[('일자')].map(lambda x : x.strftime('%A'))
delv
 
data = delv.groupby(['요일','업종'])['통화건수'].sum().unstack()
data = data.iloc[[1,5,6,4,0,2,3]]      # data = data.loc[['Mon','Tue','Wed','Thu','Fri','Sat','Sun']]
# data.plot(kind='bar')
# plt.xticks(rotation=0)
cs


# 3) 평일과 주말(금,토,일)로 그룹을 나누어서 각 그룹별 시군구별 통화건수를 분석하여라

1
2
3
4
5
6
7
d1 = {'Monday':'평일','Tuesday':'평일','Wednesday':'평일','Thursday':'평일',
     'Friday':'주말','Saturday':'주말','Sunday':'주말'}
delv['구분'= delv['요일'].map(d1)
delv.groupby(['구분','시군구'])['통화건수'].sum().unstack(level=0)
 
# data2 = delv.groupby(['요일','시군구'])['통화건수'].sum().unstack().iloc[[1,5,6,4,0,2,3]]   
# data2.groupby(['평일','평일','평일','평일','주말','주말','주말']).sum()
cs



#. Q2

### 1. 부동산_매매지수.csv 파일을 읽고

1
2
3
land = pd.read_csv('부동산_매매지수.csv', engine='python', skiprows=[0,2]) # 정수 사용 시 개수, 리스트로 묶을 시 row 위치
land.dtypes
data1 = land.dropna(how='all')  # 행 전체가 NA일 때, 삭제
cs


### 1) 2008년 4월 7일 부터 관찰된 매 주 각 구별 매매지수 기록이라고 할때 날짜컬럼을 추가

1
2
day =  pd.date_range('2008/04/07', periods=len(data1),freq='W')  
data1 = data1.set_index(day)
cs


### 2) 2017년 기준 작년 대비 상승률 상위 10개 구를 상승률과 함께 출력

1
2
3
4
5
6
7
8
9
data1.index.year
# f1 = lambda x : x.strftime('%Y')  # 연도만 추출
# data1.index.map(f1)
 
data_m = data1.resample('Y').mean()
# data1.groupby(data1.index.year).mean()
 
data2 = ((data_m - data_m.shift(1)) / data_m.shift(1* 100)['2017']
data2.stack().sort_values(ascending=False)[0:10]
cs



#. Q3

### card_history.csv파일은 올해부터 매주 일요일에 그 주의 지출 현황을 각 항목별로 기록한 데이터이다.

1
2
3
4
5
6
7
card = pd.read_csv('card_history.csv', engine='python')
 
rng = pd.date_range('2019/01/01', periods=len(card),freq='W')  
card.index = rng
card = card.iloc[:,1:]
 
card = card.applymap(lambda x : int(x.replace(',','')))
cs


# 1) 월별 각 항목의 지출 비율을 사용자 정의함수를 생성하여 출력

1
2
3
data1 = card.groupby(card.index.strftime('%m')).sum()
data2 = data1.apply(lambda x : round(x / x.sum() * 1002), axis=1)
# data1.apply(lambda x : round(x / x.sum() * 100, 2), axis=1).sum(1)
cs

 

# 2) 월별 지출 비율이 가장 높은 항목을 지출 비율과 함께 출력

1
2
data2.T.idxmax()
data2.T.loc['의복']
cs


# 3) 일별 데이터로 변경하고, 각 일별 지출내용은 하루 평균 지출값으로 나타낸다

1
2
3
4
rng = pd.date_range('2019/01/01', periods=len(card),freq='D')  
card2 = card
card2.index = rng
round(card2.mean(1),2)
cs



### 풀이

### card_history.csv파일은 올해부터 매주 일요일에 그 주의 지출 현황을 각 항목별로 기록한 데이터이다.

1
2
3
4
5
6
card = pd.read_csv('card_history.csv', engine='python')
 
card.index = pd.date_range('2019/01/01', periods=len(card),freq='W')  
card = card.drop('NUM', axis=1)
card = card.applymap(lambda x : int(x.replace(',','')))
card
cs


# 1) 월별 각 항목의 지출 비율을 사용자 정의함수를 생성하여 출력

1
2
data1 = card.resample('M').sum()
data1 = data1.apply(lambda x : round(x / x.sum() * 1002), axis=1)
cs


# 2) 월별 지출 비율이 가장 높은 항목을 지출 비율과 함께 출력

1
2
3
data2 = data1.stack()
top = lambda data,n=1 : data.sort_values(ascending=False)[:n]
data2.groupby(level=0, group_keys=False).apply(top)
cs


# 3) 일별 데이터로 변경하고, 각 일별 지출내용은 하루 평균 지출값으로 나타낸다

1
round(card.resample('D', fill_method='ffill')/7)
cs



#. Q4

1
2
3
4
5
6
7
import pandas as pd
import numpy as np
from pandas import Series, DataFrame
from numpy import nan as NA
import matplotlib.pyplot as plt
from datetime import datetime
%matplotlib qt
cs

 

### 1. movie_ex1.csv 파일을 읽고

1
mov = pd.read_csv('movie_ex1.csv',engine='python')
cs

 

# 1) 요일별 연령대의 극장 이용률 평균 구하여라

1
2
3
4
5
6
7
8
9
10
11
12
mov.dtypes # int는 결합이 될 수 없음
day = mov['년'].map(str+ '/' + mov['월'].map(str+ '/' + mov['일'].map(str)
pd.to_datetime(day) # %Y%m%d 순으로 저장된 문자열은 포맷 없이도 파싱 가능
mov['요일'= pd.to_datetime(day).map(lambda x : x.strftime('%A')) 
 
mov.groupby(['요일','연령대'])['이용_비율(%)'].mean().unstack() 
 
f1 = lambda x,y,z : datetime(x,y,z)
f1(2019,12,13)
list(map(f1, mov['년'], mov['월'], mov['일']))
# map 메서드 : 함수 인자 전달의 개수 제한
# map 함수 : 함수 인자 전달개수 제한 없음
cs

 

# 2) 서울에서 극장 이용률이 가장 높은 지역을 찾고,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 그 지역의 각 연령대별로 성별 이용률을 비교하기 위한 막대그래프 출력
mov['지역-시도'].unique()
seoul = mov[mov['지역-시도'== '서울특별시']
seoul.groupby('지역-시군구')['이용_비율(%)'].mean()
seoul.groupby('지역-시군구')['이용_비율(%)'].mean().sort_values(ascending=False)
 
a1 = seoul.groupby('지역-시군구')['이용_비율(%)'].mean().idxmax()
data1 = seoul[seoul['지역-시군구'== a1]
data1.groupby(['연령대','성별'])['이용_비율(%)'].mean()
plot1 = data1.groupby(['연령대','성별'])['이용_비율(%)'].mean().unstack() 
 
plt.rc('font', family='MalGun Gothic')
plot1.plot(kind='bar')
plt.xticks(rotation=0)
cs

 

### 2. taxi_call.csv 파일을 읽고

1
2
taxi = pd.read_csv('taxi_call.csv',engine='python')
taxi
cs

 

# 1) 각 구별로 통화건수가 가장 많은 시간대와 발신지 및 통화건수를 함께 출력

1
2
3
4
data1 = taxi.groupby(['발신지_시군구','시간대'])['통화건수'].sum()
data1.loc[('중랑구'),12# 상위,하위 순차 색인 가능
data1[data1.groupby(level=0).idxmax()]
data1.loc[data1.groupby(level=0).idxmax()]
cs

 

# 2) 오전,오후,야간,심야 시간대 별로 각 구별 택시 이용 현황을 출력

1
2
3
# 05 ~ 12 : 오전 # 12 ~ 20 : 오후 # 20 ~ 24 : 야간 # 24 ~ 05 : 심야
taxi['구분'= pd.cut(taxi['시간대'], [0,5,12,20,24], right=False, labels=['심야','오전','오후','야간'])
taxi.groupby(['발신지_시군구','구분'])['통화건수'].sum()
cs



반응형
댓글
최근에 올라온 글
최근에 달린 댓글
링크
Total
Today
Yesterday