데이터시각화 기말고사
작성 완료
-
1, 2번 푸는데 1시간 걸림... 어렵다...
-
아니 왜 plot HTML로 바꿔 올리면 에러남...
import pandas as pd
import folium
import json
import requests
df = pd.read_html('https://ncv.kdca.go.kr/mainStatus.es?mid=a11702000000', encoding = 'utf-8')[1]
df
-
합계는 필요없는것 같다
df_ = df.copy()
df_ = df_.iloc[1:,:].reset_index(drop = True) ## df와 df2의 인덱스번호를 맞춰주기 위함
global_url = 'https://raw.githubusercontent.com/southkorea/southkorea-maps/master/kostat/2018/json/skorea-provinces-2018-geo.json'
global_dict = json.loads(requests.get(global_url).text)
df_.loc[:, ('구분','구분')] = [global_dict['features'][i]['properties']['name'] for i in range(17)]
df2 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv')
df2
df2['prob'] = df_[('2차접종', '당일 누계')] / df2['총인구수 (명)']
df2 = df2.rename(columns = {'행정구역(시군구)별':'prov'}).drop('총인구수 (명)', axis = 1)
df2
m = folium.Map(scrollWheelZoom = False,
location = [36,128],
zoom_start = 8.2)
folium.Choropleth(
data = df2,
geo_data = global_dict,
columns = ['prov', 'prob'],
key_on = 'feature.properties.name'
).add_to(m)
# m
df = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/covid19_20211202.csv')
df
df3 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv')
df3
df3 = df3.rename(columns = {'행정구역(시군구)별':'prov', '총인구수 (명)':'pop'})
-
검역은 지도에 표시 안할거니 제외
df_ = df.copy()
df_.iloc[1:, 1:] = df_.iloc[1:, 1:].applymap(lambda x: int(x.replace(',', '')) if x != '-' else 0)
df_ = df_.iloc[1:, :-1].drop('계(명)', axis = 1)
df_['일자'] = df_['일자'].apply(lambda x: str(x)[:-3])
df_
_df = df_.groupby('일자').agg('sum').reset_index().\
rename(columns = dict(zip(df_.columns, ['ym'] + [global_dict['features'][i]['properties']['name'] for i in range(17)]))).\
query('"2021-01" <= ym <= "2021-10"').\
melt(id_vars = 'ym').rename(columns = {'variable':'prov', 'value':'confirmed'})
_df = _df.assign(pop = [df3.query('prov == @_df["prov"][@i]')['pop'].pipe(int) for i in range(len(_df))]).\
eval('prop = confirmed / pop')
_df
-
지금까지 고생해서 만든 데이터프레임은 시도별 월별 코로나수 확진자 수이다
# from IPython.display import HTML
# fig = px.choropleth_mapbox(_df,
# 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, _df.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}))
# HTML(_html)
-
위 코드를 실행하면 컴퓨터가 맛이가서 전부 주석처리했다
df4 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/covid19_20211202.csv')
df4
-
위의 데이터프레임을 전처리한것이 아래다
-
누적과 합계를 제외하고 검역도 제외했다
-
관찰치를 int형으로 바꾸고 -은 0으로 처리했다
df4.iloc[1:, 1:] = df4.iloc[1:, 1:].applymap(lambda x: int(x.replace(',', '')) if x != '-' else 0)
df4 = df4.iloc[1:, :-1].drop('계(명)', axis = 1)
df4.columns = ['date'] + [global_dict['features'][i]['properties']['name_eng'] for i in range(17)]
df4
import matplotlib.pyplot as plt
df4.plot.line(x = 'date', subplots = True, layout = (9, 2), figsize = (15, 15))
plt.tight_layout()
-
데이터프레임을 tidy하게 만들면된다
df4 ## 현재 데이터프레임 상태
df4_ = df4.melt(id_vars = 'date').rename(columns = {'variable':'prov'})
df4_
# fig = df4_.plot.line(backend = 'plotly',
# x = 'date',
# y = 'value',
# color = 'prov',
# facet_col = 'prov',
# facet_col_wrap = 3,
# height = 1000)
# fig.update_yaxes(matches = None)
# HTML(fig.to_html(include_mathjax = False, config = dict({'scrollZoom':False})))
df5 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-10-25-FIFA22_official_data.csv')
df5.head()
abilities = ['Crossing', 'Finishing', 'HeadingAccuracy', 'ShortPassing',
'Volleys', 'Dribbling', 'Curve', 'FKAccuracy',
'LongPassing', 'BallControl', 'Acceleration', 'SprintSpeed',
'Agility', 'Reactions', 'Balance', 'ShotPower',
'Jumping', 'Stamina', 'Strength', 'LongShots',
'Aggression', 'Interceptions', 'Positioning', 'Vision',
'Penalties', 'Composure', 'StandingTackle', 'SlidingTackle']
-
일단 Korea Republic을 Korea로 바꾼다
df5['Nationality'] = df5['Nationality'].replace('Korea Republic', 'Korea')
mean_ = ['mean'] * len(abilities)
df5_ = df5.query('Nationality == "Korea" or Nationality == "Japan"').\
groupby('Nationality').agg(dict(zip(abilities, mean_))).\
stack().reset_index().rename(columns = {'level_1':'aility', 0:'value'})
df5_['value'] = round(df5_['value'], 2)
df5_
# y = 'aility',
# x = 'value',
# barmode = 'group',
# color = 'Nationality',
# text = 'value',
# height = 1500,
# width = 800)
# HTML(fig.to_html(include_mathjax = False, config = dict({'scrollZoom':False})))
-
plotly는 따로 barh가 없으니 x와 y를 바꾸자
_df5 = df5.copy()
players = _df5.groupby('Nationality').agg('size').reset_index().\
sort_values(0, ascending = False).iloc[:20, 0].pipe(set)
players
-
위는 선수 수가 많은 상위 20개 나라
overall = set(_df5.groupby('Nationality').agg({'Overall':'mean'}).\
sort_values('Overall', ascending = False).iloc[:20,:].T.columns.tolist())
overall
-
위는 Overall이 높은 상위 20개 나라
best = list(overall.intersection(players))
best
-
위는 overall과 players의 교집합
df5.query('Nationality in @best').\
groupby('Nationality').agg({'Age':'mean'}).\
sort_values('Age', ascending = False).\
plot.bar()
-
Argentina 선수들의 평균 연령이 제일 높고 그 다음은 Brazil 마지막은 Portugal 이다
-
내가 임의로 만든 데이터
from plotnine import *
gdp = [500, 600, 620, 700, 900, 800, 770, 765, 1102, 1155, 1320, 1500, 1900, 1950, 2200]
year = list(range(1990, 2005))
unfair = [58, 60, 61, 57, 58.2, 59.7, 63.5, 62.7, 57.5, 56.8, 60.2, 59.2, 58.2, 57.8, 61.3]
govern = ['A'] * 5 + ['B'] * 5 + ['C'] * 5
Data = pd.DataFrame({'gdp':gdp, 'year':year, 'unfair':unfair, 'govern':govern})
Data
a = Data.loc[[5]]
b = Data.loc[[10]]
a['govern'] = 'A'
b['govern'] = 'B'
Data = pd.concat([Data.loc[:4], a, Data.loc[5:9], b, Data.loc[10:]])
Data
-
C만 5개여서 불편...
ggplot(Data, aes(x = 'gdp', y = 'unfair')) + geom_point() +\
geom_text(aes(label = 'year'), size = 8, va = 'bottom', ha = 'left') +\
geom_path(aes(color = 'govern'), size = 2, alpha = 0.7)
ggplot(Data, aes(x = 'gdp', y = 'unfair')) + geom_point() +\
geom_text(aes(label = 'year'), size = 8, va = 'bottom', ha = 'left') +\
geom_line(aes(color = 'govern'), size = 2, alpha = 0.7)
-
geom_line과 geom_path의 차이
-
geom_path는 선이 year를 따라간다
-
geom_line는 선이 왼쪽에서 오른쪽으로 간다(예컨대 1993다음은 1994이지만 1993 바로 오른쪽(같은 색깔중)에 1995가 있어서 1995로 간다)
-
실제 문제
from plotnine import *
df = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/gdp_df1.csv')
df
df2 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/gdp_df2.csv', index_col = 0)
df2
df_ = df2.T.reset_index().rename(columns = {'index':'Government'}).merge(df)
df_
ggplot(df_) + geom_path(aes(x = 'GDP', y = 'Inequality', size = 'pop', color = 'Government'))
df3 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/gdp_df3.csv', index_col = 0)
df3
df__ = df3.reset_index().rename(columns = {'index':'Government'}).merge(df_)
df__
ggplot(df__) + geom_path(aes(x = 'GDP', y = 'Inequality', size = 'pop', color = 'Government', linetype = 'type'))
df6 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/phone.csv')
df6
df6.set_index('Date').\
plot.line(figsize = (10, 7))
df6.set_index('Date').\
plot.line(figsize = (10, 15), subplots = True, layout = (8, 2))
plt.tight_layout()
df6.set_index('Date').stack().reset_index().rename(columns = {'level_1':'variable', 0:'value'}).\
groupby('variable').agg('sum').sort_values('value', ascending = False).\
plot.bar()
df6_ = df6.copy()
df6_.Date = df6_.Date.apply(lambda x: str(x)[:4])
_df6 = df6_.query('Date == "2019"').melt(id_vars = 'Date').groupby('variable').agg('sum')
_df6['value'] = _df6['value'] / _df6.value.sum()
_df6
_df6.rename(columns = {'value':'2019'}).\
plot.pie(y = '2019', figsize = (7, 7))
df7 = df6.set_index('Date').stack().reset_index().rename(columns = {'level_1':'variable', 0:'value'}).\
groupby('Date').agg('sum').reset_index()
df7
df7.Date = df7.Date.apply(lambda x: str(x)[:4])
df7
df7.groupby('Date').agg('mean').\
plot.bar()
import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # 한글이 깨지지 않도록 설정
matplotlib.rcParams['axes.unicode_minus'] = False # 한글이 깨지지 않도록 설정
df7 = pd.read_html('https://ko.wikipedia.org/wiki/%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD%EC%9D%98_%EC%9D%B8%EA%B5%AC')[17]
df7
df7.iloc[:-1, :].set_index('지역')
df7.iloc[:-1, :].set_index('지역').plot.pie(y = '출생아 수(천명)')
df8 = pd.read_html('https://ko.wikipedia.org/wiki/%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD%EC%9D%98_%EC%9D%B8%EA%B5%AC')[18]
df8
df9 = df8.rename(columns = {'Unnamed: 0':'지역'}).iloc[1:, :].\
sort_values('지역').set_index('지역').\
applymap(lambda x: float(x) if x != '-' else 0)
df9
lst = df7.iloc[:-1, :].sort_values('지역').loc[:, ['지역', '합계출산율']].\
rename(columns = {'합계출산율':'2020'}).set_index('지역').index.tolist()
lst
-
matplotlib 사용(untidy data)
df7.iloc[:-1, :].sort_values('지역').loc[:, ['지역', '합계출산율']].\
rename(columns = {'합계출산율':'2020'}).set_index('지역').\
rename(index = dict(zip(lst, df9.index))).reset_index().\
merge(df9.reset_index()).set_index('지역').T.\
plot.line(figsize = (10, 6))
-
plotly 사용(tidy data)
# rename(columns = {'합계출산율':'2020'}).set_index('지역').\
# rename(index = dict(zip(lst, df9.index))).reset_index().\
# merge(df9.reset_index()).melt(id_vars = '지역').\
# rename(columns = {'variable':'year', 'value':'birth_rate'}).\
# plot.line(x = 'year', y ='birth_rate', color = '지역', backend = 'plotly')