본문 바로가기
문송충의 코딩하기/파이썬 데이터 분석

[파이썬] - 서울 2호선 지하철 역별 승하차 승객 수 Folium으로 시각화

by 동장군님 2020. 11. 27.
728x90
반응형

이번 포스팅에서는 서울 열린 데이터 광장에서 제공하는 지하철 역별 승하차 승객 수 데이터를 API로 가져온 다음 Folium으로 시각화해보도록 하겠다. 2호선 어느 역에서 승차 승객 수가 많은 지 지도로 그려보면서 파이썬 시각화 연습을 해보고자 한다. 서울시 지하철 승하차 관련 데이터는 아래 링크에서 확인이 가능하다. 당연한 얘기이겠지만 API 데이터를 사용하려면 API 키 값을 신청해야 한다.

 

data.seoul.go.kr/dataList/OA-12914/S/1/datasetView.do

 

서울시 지하철호선별 역별 승하차 인원 정보

데이터 이용하기-서울시 지하철호선별 역별 승하차 인원 정보

data.seoul.go.kr

 

서울 열린 데이터 API에서 데이터 가져오기

 

하루치 데이터를 가져오면 데이터의 표본이 너무 적을 것 같아서 10월 1일부터 31일까지의 한 달치 데이터를 가져와서 역별 10월 평균 승하차 승객 수치를 계산해보도록 하겠다.

 

import pandas as pd
import requests

key='~'
re=requests.get(f'http://openapi.seoul.go.kr:8088/{key}/json/CardSubwayStatsNew/1/999/20201101')

subway=dict()
for i in range(1,32):
    if i <10:
        re=requests.get(f'http://openapi.seoul.go.kr:8088/{key}/json/CardSubwayStatsNew/1/999/2020100{i}')
        data=re.json()
        date='2020100'+str(i)
    else:
        re=requests.get(f'http://openapi.seoul.go.kr:8088/{key}/json/CardSubwayStatsNew/1/999/202010{i}')
        data=re.json()
        date='202010'+str(i)
    station=[]
    take_on=[]
    take_off=[]
    for v in data['CardSubwayStatsNew']['row']:
        if v['LINE_NUM']=='2호선':
                station.append(v['SUB_STA_NM'])
                take_on.append(v['RIDE_PASGR_NUM'])
                take_off.append(v['ALIGHT_PASGR_NUM'])
    subway[date]=[
        {'station':station,'승차인원':take_on,'하차인원':take_off}
    ]
    
df=pd.DataFrame(index=subway['20201001'][0]['station'],columns=subway.keys())
for i in subway:
    for v in subway[i]:
        df[i]=v['승차인원']
ride=pd.DataFrame(df.mean(axis=1),columns=['평균 승차 승객 수'])

fd=pd.DataFrame(index=subway['20201001'][0]['station'],columns=subway.keys())
for i in subway:
    for v in subway[i]:
        fd[i]=v['하차인원']
off=pd.DataFrame(fd.mean(axis=1),columns=['평균 하차 승객 수'])

table=pd.merge(left=ride,right=off,how='inner',left_on=ride.index,right_on=off.index)
table=table.rename(columns={'key_0':'역명'})
table=table.sort_values(by='역명',ascending=True)

 

위에서 생성한 table 변수를 출력하면 아래와 같은 서울 2호선 역별 10월 평균 승하차 승객 수를 확인할 수 있을 것이다. 역시나 강남역에서의 승하차 승객수가 가장 많았다.

 

 

 

승하차 승객 수 Top 10 시각화

 

우선 승하차 승객 별로 내림차순 정렬을 하도록 하겠다.

table['평균 승차 승객 수']=table['평균 승차 승객 수'].astype(int)
table['평균 하차 승객 수']=table['평균 하차 승객 수'].astype(int)
top10_ride=table.sort_values(by='평균 승차 승객 수',ascending=False)
top10_off=table.sort_values(by='평균 하차 승객 수',ascending=False)

 

승차 승객 수에서는 강남>잠실>신림>구디단>홍대 순으로 높게 나타났다.

 

import matplotlib.pyplot as plt

plt.rcParams["font.family"] = 'Malgun Gothic'
plt.figure(figsize=(16,8))

plt.bar(top10_ride['역명'][:10],top10_ride['평균 승차 승객 수'][:10])
for x,y in enumerate(list(top10_ride['평균 승차 승객 수'][:10])):
    plt.text(x, y, y, fontsize=10, color='#ff0000', 
                    horizontalalignment='center', verticalalignment='bottom')
plt.title('10월 평균 승차 인원 수 Top10 2호선 역')
plt.show()

 

하차 승객 수에서는 강남>잠실>신림>홍대>구디단 순으로 높게 나타났다.

 

plt.rcParams["font.family"] = 'Malgun Gothic'
plt.figure(figsize=(16,8))

plt.bar(top10_off['역명'][:10],top10_off['평균 하차 승객 수'][:10])
for x,y in enumerate(list(top10_off['평균 하차 승객 수'][:10])):
    plt.text(x, y, y, fontsize=10, color='#ff0000', 
                    horizontalalignment='center', verticalalignment='bottom')
plt.title('10월 평균 하차 인원 수 Top10 2호선 역')
plt.show()

 

 

Folium으로 지도에 시각화 #1 - 카카오 API로 2호선 역 위도, 경도 좌표 가져오기

아래처럼 카카오 API를 통해서 위도, 경도 좌표를 가져오도록 하겠다. 단순히 강남, 잠실, 홍대 이름으로 검색할 경우 정확한 지하철 좌표를 못 가져오기 때문에 여기서는 모든 역 이름에 '역'을 붙이도록 하겠다.

 

import re
table['역명']=table['역명'].apply(lambda x: re.sub(r'\([^)]*\)', '', x) if '(' in x else x)
table['역명']=table['역명'].apply(lambda x: x+'역')

x=[]
y=[]
for z in table['역명']:

    url = 'https://dapi.kakao.com/v2/local/search/keyword.json?query={}'.format(z)
    headers = {
        "Authorization": "KakaoAK ~"
    }
#json 형태로 데이터가 주어진다
    places = requests.get(url, headers = headers).json()['documents'][0]
    x.append(places['y'])
    y.append(places['x'])
    
table['latitude']=x
table['longitude']=y
table2=table.reset_index()    
table2['평균 승차 승객 수']=table2['평균 승차 승객 수'].astype(float)

 

 

Folium으로 지도에 시각화 #2 - Folium으로 시각화

위에서 전처리한 데이터를 갖고 아래와 같이 코드를 돌리면 무난히 시각화가 성공할 것이다. 여기서는 승차 승객 수를 기준으로 원 크기를 정했다. 위에서 언급했던 것과 같이 강남역, 잠실역, 구로디지털단지역에서의 원 크기가 높은 점을 확인할 수가 있다.

import folium
map=folium.Map(location=[37.51883692578755, 126.98948248323136],zoom_start=12)
for i in table2.index:
    folium.CircleMarker([table2['latitude'][i],table2['longitude'][i]],radius=table2['평균 승차 승객 수'][i]/2000,
                        popup=table2['역명'][i],color='#3186cc', fill_color='#3186cc').add_to(map)

 

 

 

 

728x90
반응형

댓글