[서울시 지하철 시간대별 데이터 2015~2019] 지하철 시간별 승객 승하차 데이터 EDA - (1)

2020. 11. 24. 19:01Project/지하철 데이터를 활용한 서울 상가거래 예측

※ "BC 금융 빅데이터 플랫폼 공모전 - 젠트리피케이션 예측" 프로젝트에서 방향성을 전환하여 새롭게 시작하는 분석입니다. 

※ 데이터는 전처리 후 사용했기에 현재 압축시 약 60MB정도 됩니다. 2015~2019 서울 1~8호선 시간대별 승하차 승객수를 나타내는 데이터로 1000000 row 정도입니다. 필요하실 경우 메일링크를 남겨주시면 보내드리겠습니다. 


# library load

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

from mpl_toolkits.mplot3d import axes3d
from matplotlib import style
import seaborn as sns

import matplotlib as mpl
import matplotlib.font_manager as fm
import matplotlib.colors as mcolors
mpl.rcParams['axes.unicode_minus'] = False

# 한글깨짐 발생 - font 찾기
[(f.name, f.fname) for f in fm.fontManager.ttflist if 'Nanum' in f.name]

plt.rcParams["font.family"] = 'NanumGothic'
plt.rcParams["font.size"] = 10
plt.rcParams["figure.figsize"] = (14,4)
# data load & simple preprocessing

subway = pd.read_csv("서울 지하철 1~8호선 종합_최종.csv",encoding = 'cp949')
subway['날짜'] = pd.to_datetime(subway['날짜'], format='%Y-%m-%d')
subway.drop(["Unnamed: 0",'연번','역주소','역번호'],axis = 1, inplace = True)
subway.head(1)

 

# 전체 역 정보 확인
# 추후 function의 parameter로 넣을 때, 찾기 편하도록 출력
for i in range(subway[['역명','호선']].drop_duplicates().shape[0]) :
    print("{}호선 {}".format(subway[['역명','호선']].drop_duplicates()['호선'].iloc[i],
                            subway[['역명','호선']].drop_duplicates()['역명'].iloc[i]), end = ',' )

 

- 지하철 유동인구 -

가장 많은 승하차 시간대에 주목 : 시간대가 방문객의 특성을 나타낼 것이라는 가정.

 

1. 시간대별 년도에 따른 data 분포 확인 - (1) 

 

이러한 유동인구의 변화 및 시간대적인 특성이 상업용 부동산에 영향을 미칠 것이라고 판단. 그렇기에 승객에 대한 정보를 확인하기 위해 EDA 진행

#!pip install mpltools

import cycler

n = 24
color = plt.cm.Accent(np.linspace(0, 1,n))
mpl.rcParams['axes.prop_cycle'] = cycler.cycler('color', color)

def plot_station(df,name,line = None ,type_ = None):
    
    if type_ == None : 
        df_station = df[df['역명'] == name]
    else : 
        df_station = df[df['역명'] == name][df[df['역명'] == name]['구분'].str.contains(type_)]
    
    if line == None :
        df_station_line = df_station
    else : 
        df_station_line = df_station[df_station['호선'] == line]
    
    s2015 = df_station_line.iloc[0:365,:-4]
    s2016 = df_station_line.iloc[365:365+366,:-4]
    s2017 = df_station_line.iloc[365+366:365+366+365,:-4]
    s2018 = df_station_line.iloc[365+366+365:365+366+365+365,:-4]
    s2019 = df_station_line.iloc[365+366+365+365:,:-4]

    s2015 = s2015.drop('구분',axis=1).set_index('날짜')
    s2016 = s2016.drop('구분',axis=1).set_index('날짜')
    s2017 = s2017.drop('구분',axis=1).set_index('날짜')
    s2018 = s2018.drop('구분',axis=1).set_index('날짜')
    s2019 = s2019.drop('구분',axis=1).set_index('날짜')
    
    plt.figure(figsize=(30,20))
        
    plt.subplot(511)
    plt.plot(s2015)
    plt.legend(labels = tuple(s2015.columns),fontsize = 'xx-small')

    plt.subplot(512)
    plt.plot(s2016)

    plt.subplot(513)
    plt.plot(s2017)

    plt.subplot(514)
    plt.plot(s2018)

    plt.subplot(515)
    plt.plot(s2019)

 

# 홍대입구역 승차

plot_station(df = subway, name = '홍대입구', line = 2, type_ = '승차')

# 여의도역 승차

plot_station(df = subway, name = '여의도', line = 5, type_ = '승차')

 

위의 plot_station은 년도별 승하차 승객수의 시간대별 추이를 나타내는 plot을 출력하는 함수이다. 위를 다양한 역들과 승하차를 parameter로 주어 확인해보면, 다양한 해석이 가능하다.

- 홍대 vs 여의도  
> - 홍대의 경우 5 ~ 8pm 하차를 가장 많이하고, 8 ~ 11pm에 승차를 가장 많이함  
> - 여의도의 경우 10am 이전 하차를 가장 많이하고, 5pm~8pm 승차를 가장 많이함  
 - 지역의 목적이 분명하게 분리된다고 생각 

- 석촌 호수 : 하차 시간대가 출근시간대에서 퇴근시간대로 점점 증가  

등..

# 파생 dataset 생성

subway_groupby = subway.groupby(['날짜','역명','구분']).sum().drop(['호선','위도','경도'],axis=1)
subway_groupby = subway_groupby.reset_index()

take_sum_line = subway_groupby[subway_groupby['구분'] == '승차']
off_sum_line = subway_groupby[subway_groupby['구분'] == '하차']

take_sum_line.drop('구분',axis=1,inplace = True)
off_sum_line.drop('구분',axis=1,inplace = True)

take_sum_line.set_index('날짜',inplace = True)
off_sum_line.set_index('날짜',inplace = True)

 

2. 시간대별 년도에 따른 data 분포 확인 - (2)

 

 

# 년도마다 시간대에 따른 승하차 승객수 확인 함수 

def Y_max_time(take_df,off_df,name,type_ = None) :
    
    if type_ == 'df':
        return df[df['역명'] == name].resample('Y').mean().T.style.background_gradient(cmap = 'Wistia')
    else :
        plt.figure(figsize=(20,5))     
        plt.subplot(121)
        plt.xticks(rotation = 70)
        plt.title('승차')
        plt.plot(take_df[take_df['역명'] == name].resample('Y').mean().T)
        plt.legend(labels = take_df.index)
        
        
        
        plt.subplot(122)
        plt.xticks(rotation = 70)
        plt.title('하차')
        plt.plot(off_df[off_df['역명'] == name].resample('Y').mean().T)
        plt.legend(labels = off_df.index)
        
    
# 파생 dataset 사용, 홍대입구의 시간대별 추이 그래프

Y_max_time(take_sum_line,off_sum_line, '홍대입구')

# 파생 dataset 사용, 여의도의 시간대별 추이 그래프

Y_max_time(take_sum_line,off_sum_line, '여의도')
    

위의 특징을 통해 특정 지하철의 시간대별 승객 변화는 년도가 지나가도 비슷한 형태를 띔을 알 수 있다.