기말고사 1~2번풀이
아래의 그림은 COVID19 예방접종의 시도별 현황을 캡쳐한 것이다.
이 정보는 특정 주기로 업데이트 되며 아래의 웹페이지 2번째 테이블에서 확인할 수 있다.
https://ncv.kdca.go.kr/mainStatus.es?mid=a11702000000
판다스의 pd.read_html()
함수를 이용해 위의 페이지에서 그림1의 테이블을 읽어오라. 그리고 folium의 choroplethmap을 활용하여 시도별 2차접종의 접종률을 시각화 하라. 시각화 예시는 아래와 같다.
(풀이)
-
데이터프레임 읽어오기
import pandas as pd
df=pd.read_html('https://ncv.kdca.go.kr/mainStatus.es?mid=a11702000000',encoding='utf-8')[1]
df
-
json 파일
import json
import requests
global_distriction_jsonurl='https://raw.githubusercontent.com/southkorea/southkorea-maps/master/kostat/2018/json/skorea-provinces-2018-geo.json'
global_dict = json.loads(requests.get(global_distriction_jsonurl).text)
prov=[global_dict['features'][i]['properties']['name'] for i in range(17)]
prov
-
변형
df.iloc[1:,1:].assign(prov=prov)
df.iloc[1:,1:].assign(prov=prov).\
set_index('prov').stack().stack().reset_index().rename(columns={0:'value'})
df.iloc[1:,1:].assign(prov=prov).\
set_index('prov').stack().stack().reset_index().rename(columns={0:'value'}).\
query('level_1 == "당일 누계" and level_2 == "2차접종" ' )
-
머지할 데이터프레임을 찾자
pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv')
pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv').\
rename(columns={'행정구역(시군구)별':'prov','총인구수 (명)':'pop'}) ## 머지할 df <-- 이름 줄 가치가 X
-
머지
df.iloc[1:,1:].assign(prov=prov).\
set_index('prov').stack().stack().reset_index().rename(columns={0:'value'}).\
query('level_1 == "당일 누계" and level_2 == "2차접종" ' ).\
merge(pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv').\
rename(columns={'행정구역(시군구)별':'prov','총인구수 (명)':'pop'}))
df.iloc[1:,1:].assign(prov=prov).\
set_index('prov').stack().stack().reset_index().rename(columns={0:'value'}).\
query('level_1 == "당일 누계" and level_2 == "2차접종" ' ).\
merge(pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv').\
rename(columns={'행정구역(시군구)별':'prov','총인구수 (명)':'pop'})).\
eval('prop= value / pop')
_df=df.iloc[1:,1:].assign(prov=prov).\
set_index('prov').stack().stack().reset_index().rename(columns={0:'value'}).\
query('level_1 == "당일 누계" and level_2 == "2차접종" ' ).\
merge(pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv').\
rename(columns={'행정구역(시군구)별':'prov','총인구수 (명)':'pop'})).\
eval('prop= value / pop')
-
저장
import folium
m = folium.Map([36,128],zoom_start=7,scrollWheelZoom=False)
choro = folium.Choropleth(
data = _df,
geo_data= global_dict,
columns=['prov','prop'],
key_on = 'feature.properties.name'
)
choro.add_to(m)
#m
아래는 COVID19 확진자수를 지역별로 매일 기록한 자료이다.
https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/covid19_20211202.csv
자료를 판다스로 불러온 결과는 아래와 같다.
일별로 기록된 COVID19 확진자수를 월별로 통합한 뒤 2021-01 ~ 2021-10
기간의 발생률을 계산하여 시각화하라. 시각화는 plotly
의 choropleth_mapbox
를 이용하며 시간의 추이를 표현하기 위해 animation_frame
옵션을 사용한다. 시각화 예시는 생략함.
(풀이)
df = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/covid19_20211202.csv')
df
df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0))
df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0)).\
T.reset_index().rename(columns={'index':'prov'}).assign(prov=prov).set_index('prov').T.reset_index()
df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0)).\
T.reset_index().rename(columns={'index':'prov'}).assign(prov=prov).set_index('prov').T.reset_index()
-
여기가 어려움. 아래의 변환이 필요함
'2020-01-20', '2020-01'
'2020-01-20'[:7]
'2020-01-20'.split('-')[0]+ '-' + '2020-01-20'.split('-')[1]
-
방법1
_df=df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0)).\
T.reset_index().rename(columns={'index':'prov'}).assign(prov=prov).set_index('prov').T.reset_index()
_df.assign(일자=list(map(lambda x: x[:7] , _df['일자'])))
-
방법2
df.assign(일자=list(map(lambda x: x[:7], df.일자 )))
- 현실적으로 이정도까지 앞을 내다보는건 힘든것 같아요..
-
방법3
df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0)).\
T.reset_index().rename(columns={'index':'prov'}).assign(prov=prov).set_index('prov').T.reset_index().\
assign(일자=lambda df: list(map(lambda x: x[:7] , df['일자'])))
-
방법3을 택하도록 하자. 위에서 일자를 ym으로 바꾸고 tidydata를 만들자.
df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0)).\
T.reset_index().rename(columns={'index':'prov'}).assign(prov=prov).set_index('prov').T.reset_index().\
assign(일자=lambda df: list(map(lambda x: x[:7] , df['일자']))).\
rename(columns={'일자':'ym'}).set_index('ym').stack().reset_index().rename(columns={0:'value'})
-
groupby 적용
df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0)).\
T.reset_index().rename(columns={'index':'prov'}).assign(prov=prov).set_index('prov').T.reset_index().\
assign(일자=lambda df: list(map(lambda x: x[:7] , df['일자']))).\
rename(columns={'일자':'ym'}).set_index('ym').stack().reset_index().rename(columns={0:'value'}).\
groupby(['ym','prov']).agg({'value':sum}).reset_index()
-
query
df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0)).\
T.reset_index().rename(columns={'index':'prov'}).assign(prov=prov).set_index('prov').T.reset_index().\
assign(일자=lambda df: list(map(lambda x: x[:7] , df['일자']))).\
rename(columns={'일자':'ym'}).set_index('ym').stack().reset_index().rename(columns={0:'value'}).\
groupby(['ym','prov']).agg({'value':sum}).reset_index().\
query('ym >= "2021-01" and ym<="2021-10"')
-
merge
df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0)).\
T.reset_index().rename(columns={'index':'prov'}).assign(prov=prov).set_index('prov').T.reset_index().\
assign(일자=lambda df: list(map(lambda x: x[:7] , df['일자']))).\
rename(columns={'일자':'ym'}).set_index('ym').stack().reset_index().rename(columns={0:'value'}).\
groupby(['ym','prov']).agg({'value':sum}).reset_index().\
query('ym >= "2021-01" and ym<="2021-10"').\
merge(pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv').\
rename(columns={'행정구역(시군구)별':'prov','총인구수 (명)':'pop'})) ## 머지할 df <-- 이름 줄 가치가 X
-
prop = value / pop 을 계산하자
df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0)).\
T.reset_index().rename(columns={'index':'prov'}).assign(prov=prov).set_index('prov').T.reset_index().\
assign(일자=lambda df: list(map(lambda x: x[:7] , df['일자']))).\
rename(columns={'일자':'ym'}).set_index('ym').stack().reset_index().rename(columns={0:'value'}).\
groupby(['ym','prov']).agg({'value':sum}).reset_index().\
query('ym >= "2021-01" and ym<="2021-10"').\
merge(pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv').\
rename(columns={'행정구역(시군구)별':'prov','총인구수 (명)':'pop'})).\
eval('prop = value/pop')
df2=df.iloc[1:].set_index('일자').iloc[:,1:-1].applymap(lambda x: int(x.replace(',','') if x!='-' else 0)).\
T.reset_index().rename(columns={'index':'prov'}).assign(prov=prov).set_index('prov').T.reset_index().\
assign(일자=lambda df: list(map(lambda x: x[:7] , df['일자']))).\
rename(columns={'일자':'ym'}).set_index('ym').stack().reset_index().rename(columns={0:'value'}).\
groupby(['ym','prov']).agg({'value':sum}).reset_index().\
query('ym >= "2021-01" and ym<="2021-10"').\
merge(pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv').\
rename(columns={'행정구역(시군구)별':'prov','총인구수 (명)':'pop'})).\
eval('prop = value/pop')
# from IPython.display import HTML
# fig=px.choropleth_mapbox(df2,
# geojson=global_dict,
# color='prop',
# locations='prov',
# animation_frame='ym',
# featureidkey='properties.name',
# center={"lat": 36, "lon": 128},
# mapbox_style="carto-positron",
# range_color=(0, df2.prop.max()),
# height=1200,
# zoom=6.5)
# fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
# HTML(fig.to_html(include_mathjax=False, config=dict({'scrollZoom':False})))