기말고사 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})))