ํ๋ก์ ํธ ๋ชฉํ
- ์น์ฐจ ๋๋ ํ์ฐจ ์ ํด๋น ์๊ฐ, ํด๋น ์ญ์ ์น๊ฐ ์๋ฅผ ํ์ธํ๊ธฐ ์ํด ๊ฐ์ฐฐ๊ตฌ ํต๊ณผ ์น๊ฐ ์ ๋ฐ์ดํฐ์ ์งํ์ฒ ์์น์ขํ ๋ฐ์ดํฐ๋ฅผ ํ์ฉ
- ํ์์ ๋ฐ์ดํฐ ๋ถ์์ ์ํํ๊ธฐ ์ํ ๋ฐ์ดํฐ ์ ์ , ํน์ฑ ์์ง๋์ด๋ง, ์๊ฐํ ๋ฐฉ๋ฒ ํ์ต
ํ๋ก์ ํธ ๋ชฉ์ฐจ
- ๋ฐ์ดํฐ ์ฝ๊ธฐ: ์นํ์ฐจ ์ธ์ ์ ๋ณด ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ณ DataFrame ๊ตฌ์กฐ๋ฅผ ํ์ธ
1.1. ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ
1.2. ๋ฐ์ดํฐ ํ์ธํ๊ธฐ - ๋ฐ์ดํฐ ์ ์ : ๋ฐ์ดํฐ ํ์ธ ํ ํ ๋ณํ ๋ฐ ์ด์์น ๋ฐ์ดํฐ ์ฒ๋ฆฌ
2.1. 2021๋ 6์ ์นํ์ฐจ ์ธ์๋ง ์ถ์ถ - ๋ฐ์ดํฐ ์๊ฐํ: ๊ฐ ๋ณ์๋ณ๋ก ์ถ๊ฐ์ ์ธ ์ ์ ๋๋ feature engineering ๊ณผ์ ์ ๊ฑฐ์น๊ณ ์๊ฐํ๋ฅผ ์ดํด ๋ฐ์ดํฐ ํน์ฑ ํ์
3.1. ํธ์ ๋ณ ์ด์ฉ๊ฐ ์ ์ถ๋ ฅ
3.2. ํน์ ํธ์ ์์ ์ญ๋ณ ํ๊ท ์นํ์ฐจ ์ธ์ ๋ฐ์ดํฐ ์ถ์ถ
3.3. ํ๊ท ์นํ์ฐจ ์ธ์ ์ ๋ด๋ฆผ์ฐจ์์ผ๋ก ๋ง๋๊ทธ๋ํ ์ถ๋ ฅ
3.4. ํน์ ํธ์ ์ ํผ์ก ์ ๋์ ์์น์ขํ ๋ฐ์ดํฐ ๋ณํฉ
3.5. ํน์ ํธ์ ์ ํผ์ก ์ ๋๋ฅผ ์ง๋์ ์ถ๋ ฅ
๋ฐ์ดํฐ ์ถ์ฒ
- ์์ธ์ ์งํ์ฒ ํธ์ ๋ณ ์ญ๋ณ ์นํ์ฐจ ์ธ์ ์ ๋ณด ๋ฐ์ดํฐ: http://data.seoul.go.kr/dataList/OA-12252/S/1/datasetView.do
ํ๋ก์ ํธ ๊ฐ์
์ฝ๋ก๋ ์๊ตญ์ ์ต์ํด์ก๋ค๊ณ ๋ ํ์ง๋ง ๊ฐ๋ ๋ฐ์ผ๋ก ๋๊ฐ ๋ ์ฌ๋ ๋ง์ ๊ณณ์ ํผํ๊ณ ์ถ์ ์๊ฐ์ ์ด๋ค ์ฅ์๋ฅผ ํผํด์ผ ํ๋์ง ์์๋ณด๊ณ ์ถ์ ๋๊ฐ ์์ ๊ฒ๋๋ค. ์งํ์ฒ ์ด์ฉ ์น๊ฐ ์๋ฅผ ํ์ธํด๋ณด๋ฉด ํผ์ก๋๊ฐ ๋์ ์ง์ญ์ ํ์ธํด๋ณผ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
์ด๋ฒ ํ๋ก์ ํธ์์๋ ์์ธ ์ด๋ฆฐ ๋ฐ์ดํฐ ๊ด์ฅ์์ ์ ๊ณตํ๋ ์์ธ์ ์งํ์ฒ ํธ์ ๋ณ ์ญ๋ณ ์นํ์ฐจ ์ธ์ ์ ๋ณด ๋ฐ์ดํฐ๋ฅผ ๋ถ์ํ๊ณ ์งํ์ฒ ์ญ ์์น ์ขํ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํด ํน์ ํธ์ ์์ ์ด๋ค ์ญ์ด ๊ฐ์ฅ ํผ์กํ์ง ์ง๊ด์ ์ผ๋ก ํ์ธํด๋ด ์๋ค.
1. ๋ฐ์ดํฐ ์ฝ๊ธฐ
1.1. ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
pd.read_csv๋ฅผ ํตํ์ฌ ์นํ์ฐจ ์ธ์ ์ ๋ณด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ดํฐํ๋ ์ ํํ๋ก ์ฝ์ด์ต๋๋ค.
metro_all = pd.read_csv("./data/แแ
ฅแแ
ฎแฏแแ
ต แแ
ตแแ
กแแ
ฅแฏ แแ
ฉแแ
ฅแซแแ
งแฏ แแ
งแจแแ
งแฏ แแ
ตแแ
กแซแแ
ขแแ
งแฏ แแ
ณแผแแ
กแแ
ก แแ
ตแซแแ
ฏแซ แแ
ฅแผแแ
ฉ_20210705.csv", encoding = 'cp949')
# ์นํ์ฐจ ์ธ์ ์ ๋ณด ์์ 5๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
metro_all.head()
# ์นํ์ฐจ ์ธ์ ์ ๋ณด ๋ฐ์ดํฐํ๋ ์ ์ ๋ณด๋ฅผ ์์ฝํ์ฌ ์ถ๋ ฅํฉ๋๋ค.
metro_all.info()
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 45338 entries, 0 to 45337
Data columns (total 52 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 ์ฌ์ฉ์ 45338 non-null int64
1 ํธ์ ๋ช
45338 non-null object
2 ์งํ์ฒ ์ญ 45338 non-null object
3 04์-05์ ์น์ฐจ์ธ์ 45338 non-null int64
4 04์-05์ ํ์ฐจ์ธ์ 45338 non-null int64
5 05์-06์ ์น์ฐจ์ธ์ 45338 non-null int64
6 05์-06์ ํ์ฐจ์ธ์ 45338 non-null int64
7 06์-07์ ์น์ฐจ์ธ์ 45338 non-null int64
8 06์-07์ ํ์ฐจ์ธ์ 45338 non-null int64
'''
1.2. ๋ฐ์ดํฐ ํ์ธํ๊ธฐ
# metro_all DataFrame ์ฌ์ฉ์ ๋ฐ์ดํฐ ํ์ธ
sorted(list(set(metro_all['์ฌ์ฉ์'])))
'''
[201501,
201502,
201503,
201504,...
'''
# metro_all DataFrame ํธ์ ๋ช
๋ฐ์ดํฐ ํ์ธ
sorted(list(set(metro_all['ํธ์ ๋ช
'])))
'''
['1ํธ์ ',
'2ํธ์ ',
'3ํธ์ ',
'4ํธ์ ',
'''
# DataFrame ์งํ์ฒ ์ญ ๋ฐ์ดํฐ ํ์ธ
sorted(list(set(metro_all['์งํ์ฒ ์ญ'])))
'''
['4.19๋ฏผ์ฃผ๋ฌ์ง',
'๊ฐ๋ฅ',
'๊ฐ๋ฝ์์ฅ',
'๊ฐ์ฐ๋์งํธ๋จ์ง',
'''
# DataFrame ์งํ์ฒ ์ญ ๋ฐ์ดํฐ ๊ฐ์ ํ์ธ
len(list(set(metro_all['์งํ์ฒ ์ญ']))) #579
2. ๋ฐ์ดํฐ ์ ์
๊ฐ์ฅ ์ต๊ทผ ํ๋ฌ๊ฐ ์์ง๋ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ํน์ ํธ์ ์์ ์ด๋ค ์ญ์ด ๊ฐ์ฅ ํผ์กํ์ง ํ์ธํ๊ณ ์ ํฉ๋๋ค.
2.1. 2021๋ 6์ ์นํ์ฐจ ์ธ์๋ง ์ถ์ถ
# 2021๋
6์ ์ด ์น๊ฐ์๋ง ์ถ์ถ
metro_recent = metro_all[metro_all['์ฌ์ฉ์']==202106]
metro_recent
# ๋ถํ์ํ ์์
์ผ์ ์ปฌ๋ผ ์ ๊ฑฐ
metro_recent = metro_recent.drop(columns={'์์
์ผ์'})
metro_recent
3. ๋ฐ์ดํฐ ์๊ฐํ
3.1. ํธ์ ๋ณ ์ด์ฉ๊ฐ ์ ์ถ๋ ฅ
import matplotlib.font_manager as fm
font_dirs = ['/usr/share/fonts/truetype/nanum', ]
font_files = fm.findSystemFonts(fontpaths=font_dirs)
for font_file in font_files:
fm.fontManager.addfont(font_file)
metro_line = metro_recent.groupby(['ํธ์ ๋ช
']).mean().reset_index()
metro_line = metro_line.drop(columns='์ฌ์ฉ์').set_index('ํธ์ ๋ช
')
metro_line = metro_line.mean(axis=1).sort_values(ascending=False)
plt.figure(figsize=(20,10))
plt.rc('font', family="NanumBarunGothic")
plt.rcParams['axes.unicode_minus'] = False
metro_line.plot(kind=('bar'))
plt.show()
3.2. ํน์ ํธ์ ์์ ์ญ๋ณ ํ๊ท ์นํ์ฐจ ์ธ์ ๋ฐ์ดํฐ ์ถ์ถ
line = '2ํธ์ '
metro_st = metro_recent.groupby(['ํธ์ ๋ช
','์งํ์ฒ ์ญ']).mean().reset_index()
metro_st_line2 = metro_st[metro_st['ํธ์ ๋ช
']==line]
metro_st_line2
# ์น์ฐจ ์ธ์ ์ปฌ๋ผ๋ง ์ถ์ถ
metro_get_on = pd.DataFrame()
metro_get_on['์งํ์ฒ ์ญ'] = metro_st_line2['์งํ์ฒ ์ญ']
for i in range(int((len(metro_recent.columns)-3)/2)):
metro_get_on[metro_st_line2.columns[3+2*i]] = metro_st_line2[metro_st_line2.columns[3+2*i]]
metro_get_on = metro_get_on.set_index('์งํ์ฒ ์ญ')
metro_get_on
# ํ์ฐจ ์ธ์ ์ปฌ๋ผ๋ง ์ถ์ถ
metro_get_off = pd.DataFrame()
metro_get_off['์งํ์ฒ ์ญ'] = metro_st_line2['์งํ์ฒ ์ญ']
for i in range(int((len(metro_recent.columns)-3)/2)):
metro_get_off[metro_st_line2.columns[4+2*i]] = metro_st_line2[metro_st_line2.columns[4+2*i]]
metro_get_off = metro_get_off.set_index('์งํ์ฒ ์ญ')
metro_get_off
# ์ญ ๋ณ ํ๊ท ์นํ์ฐจ ์ธ์์ ๊ตฌํ ํ ์ ์๋ก ํ ๋ณํํ์ฌ ๋ฐ์ดํฐํ๋ ์์ผ๋ก ์ ์ฅ
df = pd.DataFrame(index = metro_st_line2['์งํ์ฒ ์ญ'])
df['ํ๊ท ์น์ฐจ ์ธ์ ์'] = metro_get_on.mean(axis=1).astype(int)
df['ํ๊ท ํ์ฐจ ์ธ์ ์'] = metro_get_off.mean(axis=1).astype(int)
df
3.3. ํ๊ท ์นํ์ฐจ ์ธ์ ์ ๋ด๋ฆผ์ฐจ์์ผ๋ก ๋ง๋๊ทธ๋ํ ์ถ๋ ฅ
2ํธ์ ๊ธฐ์ค 6์ ํ ๋ฌ๊ฐ ๊ฐ๋จ > ์ ์ค > ์ ๋ฆผ > ๊ตฌ๋ก๋์งํธ๋จ์ง > ํ๋์ ๊ตฌ > ์ ๋ฆ ์์ผ๋ก ํ๊ท ์น์ฐจ ์ธ์์ด ๋ง์์ต๋๋ค.
# ์น์ฐจ ์ธ์ ์ Top10
top10_on = df.sort_values(by='ํ๊ท ์น์ฐจ ์ธ์ ์', ascending=False).head(10)
plt.figure(figsize=(20,10))
plt.rc('font', family="NanumBarunGothic")
plt.rcParams['axes.unicode_minus'] = False
plt.bar(top10_on.index, top10_on['ํ๊ท ์น์ฐจ ์ธ์ ์'])
for x, y in enumerate(list(top10_on['ํ๊ท ์น์ฐจ ์ธ์ ์'])):
if x == 0:
plt.annotate(y, (x-0.15, y), color = 'red')
else:
plt.annotate(y, (x-0.15, y))
plt.title('2021๋
6์ ํ๊ท ์น์ฐจ ์ธ์ ์ Top10')
plt.show()
ํ๊ท ํ์ฐจ ์ธ์์ ๊ฑฐ์ ๋์ผํ๊ฒ ๊ฐ๋จ > ์ ์ค > ์ ๋ฆผ > ๊ตฌ๋ก๋์งํธ๋จ์ง > ํ๋์ ๊ตฌ > ์ญ์ผ ์์ผ๋ก ๋ง์์ต๋๋ค.
# ํ์ฐจ ์ธ์ ์ Top10
top10_off = df.sort_values(by='ํ๊ท ํ์ฐจ ์ธ์ ์', ascending=False).head(10)
plt.figure(figsize=(20,10))
plt.rc('font', family="NanumBarunGothic")
plt.rcParams['axes.unicode_minus'] = False
plt.bar(top10_off.index, top10_off['ํ๊ท ํ์ฐจ ์ธ์ ์'])
for x, y in enumerate(list(top10_off['ํ๊ท ํ์ฐจ ์ธ์ ์'])):
if x == 0:
plt.annotate(y, (x-0.15, y), color = 'red')
else:
plt.annotate(y, (x-0.15, y))
plt.title('2021๋
6์ ํ๊ท ํ์ฐจ ์ธ์ ์ Top10')
plt.show()
ํด์ฆ1. 6ํธ์ ์ ์งํ์ฒ ์ญ ์ค์์ ์น์ฐจ ์ธ์์๊ฐ ๊ฐ์ฅ ๋ง์ ์ญ๋ช ์ ๊ตฌํ์ธ์.
# 3.2.์ ์ฒซ ๋ฒ์งธ ์
์์ line๊ฐ๋ง ์์ ํ ํ
# 3.2.์ 3.3. ์ฝ๋๋ฅผ ์์๋๋ก ๋ค์ ์คํํด๋ณด๋ฉด ๋ต์ ๊ตฌํ ์ ์์ต๋๋ค.
top_on = df.sort_values(by='ํ๊ท ์น์ฐจ ์ธ์ ์', ascending=False).head(1)
top_on.index[0]
3.4. ํน์ ํธ์ ์ ํผ์ก ์ ๋์ ์์น์ขํ ๋ฐ์ดํฐ ๋ณํฉ
ํน์ ํธ์ ์ ์งํ์ฒ ์ญ ๋ง๋ค ์ง๋์ ์ ๋ณด๋ฅผ ์ถ๋ ฅํ๊ธฐ ์ํด์๋ ๊ฐ ์์น์ ์ขํ์ ๋ณด๊ฐ ํ์ํฉ๋๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์นด์นด์ค API๋ฅผ ํ์ฉํ์ฌ csv ํ์ผ๋ก ๋ง๋ค์ด๋์์ต๋๋ค.
์ถ์ฒ:
https://developers.kakao.com/docs/latest/ko/local/dev-guide#search-by-keyword
https://developers.kakao.com/docs/latest/ko/local/dev-guide#address-coord
# ์งํ์ฒ ์ญ๋ณ ์์น์ขํ์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ต๋๋ค.
subway_location = pd.read_csv('./data/์งํ์ฒ ์ญ ์์น ์ขํ.csv')
subway_location
# ํน์ ํธ์ ์ ์ญ๋ณ ํ๊ท ์นํ์ฐจ ์ธ์ ์์ ์งํ์ฒ ์ญ ์์น ์ขํ๋ฅผ ๋ฐ์ดํฐํ๋ ์์ผ๋ก ๋ฐํํ๋ ํจ์์
๋๋ค.
def get_nums_and_location(line, metro_st):
# ํน์ ํธ์ ์ ๋ฐ์ดํฐ๋ง ์ถ์ถํฉ๋๋ค.
metro_line_n = metro_st[metro_st['ํธ์ ๋ช
']==line]
# ์น์ฐจ ์ธ์ ์ปฌ๋ผ๋ง ์ถ์ถํฉ๋๋ค.
metro_get_on = pd.DataFrame()
metro_get_on['์งํ์ฒ ์ญ'] = metro_line_n['์งํ์ฒ ์ญ']
for i in range(int((len(metro_recent.columns)-3)/2)):
metro_get_on[metro_line_n.columns[3+2*i]] = metro_line_n[metro_line_n.columns[3+2*i]]
metro_get_on = metro_get_on.set_index('์งํ์ฒ ์ญ')
# ํ์ฐจ ์ธ์ ์ปฌ๋ผ๋ง ์ถ์ถํฉ๋๋ค.
metro_get_off = pd.DataFrame()
metro_get_off['์งํ์ฒ ์ญ'] = metro_line_n['์งํ์ฒ ์ญ']
for i in range(int((len(metro_recent.columns)-3)/2)):
metro_get_off[metro_line_n.columns[4+2*i]] = metro_line_n[metro_line_n.columns[4+2*i]]
metro_get_off = metro_get_off.set_index('์งํ์ฒ ์ญ')
# ์ญ ๋ณ ํ๊ท ์นํ์ฐจ ์ธ์์ ๊ตฌํ ํ ์ ์๋ก ํ ๋ณํํ์ฌ ๋ฐ์ดํฐํ๋ ์์ผ๋ก ์ ์ฅํฉ๋๋ค.
df = pd.DataFrame(index = metro_line_n['์งํ์ฒ ์ญ'])
df['ํ๊ท ์น์ฐจ ์ธ์ ์'] = metro_get_on.mean(axis=1).astype(int)
df['ํ๊ท ํ์ฐจ ์ธ์ ์'] = metro_get_off.mean(axis=1).astype(int)
# ์งํ์ฒ ์ญ ๋ช
๋์ผํ๋๋ก ์ค์ ํฉ๋๋ค.
temp = []
df = df.reset_index()
for name in df['์งํ์ฒ ์ญ']:
temp.append(name.split('(')[0]+'์ญ')
df['์งํ์ฒ ์ญ'] = temp
# ์งํ์ฒ ์ญ ๋ช
์ ๊ธฐ์ค์ผ๋ก ๋ ๋ฐ์ดํฐํ๋ ์ ๋ณํฉํฉ๋๋ค.
df = df.merge(subway_location, left_on='์งํ์ฒ ์ญ', right_on='์งํ์ฒ ์ญ')
return df
get_nums_and_location('6ํธ์ ', metro_st)
3.5. ํน์ ํธ์ ์ ํผ์ก ์ ๋๋ฅผ ์ง๋์ ์ถ๋ ฅ
import folium
# ํน์ ์๋, ๊ฒฝ๋ ์ค์ฌ์ผ๋ก ํ๋ OpenStreetMap์ ์ถ๋ ฅ
map_osm = folium.Map(location = [37.529622, 126.984307], zoom_start=12)
map_osm
# ํน์ ํธ์ ์ ์ญ๋ณ ํ๊ท ์นํ์ฐจ ์ธ์ ์์ ์์น์ขํ ๋ฐ์ดํฐ๋ง ์ถ์ถํฉ๋๋ค.
rail = '6ํธ์ '
df = get_nums_and_location(rail, metro_st)
# ์์ธ์ ์ค์ฌ์ ์์นํ๋ ๋ช
๋์ญ์ ์๋์ ๊ฒฝ๋๋ฅผ ์ค์ฌ์ผ๋ก ์ง๋ ์ถ๋ ฅํฉ๋๋ค.
latitude = subway_location[subway_location['์งํ์ฒ ์ญ']=='๋ช
๋์ญ']['x์ขํ']
longitude = subway_location[subway_location['์งํ์ฒ ์ญ']=='๋ช
๋์ญ']['y์ขํ']
map_osm = folium.Map(location = [latitude, longitude], zoom_start = 12)
# ๊ฐ ์งํ์ฒ ์ญ์ ์์น๋ณ๋ก ์ํ๋ง์ปค๋ฅผ ์ง๋์ ์ถ๊ฐํฉ๋๋ค.
for i in df.index:
marker = folium.CircleMarker([df['x์ขํ'][i],df['y์ขํ'][i]],
radius = (df['ํ๊ท ์น์ฐจ ์ธ์ ์'][i]+1)/3000, # ์ธ์ ์๊ฐ 0์ผ ๋ ๊ณ์ฐ์ค๋ฅ ๋ณด์
popup = [df['์งํ์ฒ ์ญ'][i],df['ํ๊ท ์น์ฐจ ์ธ์ ์'][i]],
color = 'blue',
fill_color = 'blue')
marker.add_to(map_osm)
map_osm
ํด์ฆ2. ๊ฐ๋จ์ญ์ x์ขํ(์๋)๋ฅผ ๊ตฌํ์ธ์.
# get_nums_and_location() ํจ์๋ฅผ ํ์ฉํ๋ฉด ์ฝ๊ฒ ๊ตฌํ ์ ์์ต๋๋ค.
# ๊ฐ๋จ์ญ์ 2ํธ์ ์ด๊ธฐ ๋๋ฌธ์ df = get_nums_and_location('2ํธ์ ', metro_st)์ผ๋ก ๋ฐ์ดํฐํ๋ ์์ ์ถ์ถํฉ๋๋ค.
# df[df['์งํ์ฒ ์ญ']=='๊ฐ๋จ์ญ']['x์ขํ']์ ํตํด ์ปฌ๋ผ '์งํ์ฒ ์ญ'์ด '๊ฐ๋จ์ญ'์ธ ํ์ ์ถ์ถํ๊ณ 'x์ขํ'๊ฐ์ ๊ตฌํด๋ณด์ธ์.
df = get_nums_and_location('2ํธ์ ', metro_st)
x = df[df['์งํ์ฒ ์ญ']=='๊ฐ๋จ์ญ']['x์ขํ']
x[0] #37.4970572543978