안녕하세요.
종강 및 퇴사 이슈로 할일이 없어진 사람입니다. 심심해서 혼자서 데이터분석 프로젝트를 진행해 보았어요.
이세상에 태어나고 두번째로 진행해본 프로젝트입니다.(첫번째껀 나중에 올리게씀)
제가 다 한 건 아니고 관련 코드 참고하여, 조금 더 발전시키고 다양하게 시각화하는 쪽으로 이것저것 해보았습니다.
(이사람 애초에 혼자 힘으로 진행한 프로젝트가 없어요..)
원래는 git로 블로그 페이지 만들고 거기다가 올리려고 했는데, git 익히는 데 오래 걸릴 것 같아서 일단 네이버 블로그로 올리기로 했습니다. velog나 Notion으로 정리하는 것도 고민했었는데, velog는 광고로 인한 가독성 이슈로, Notion은 용량 많아지면 버벅이는 이슈로 탈락해버림.. 그냥 하루빨리 git 을 익히도록 하는걸로
발표용으로 만든 자료가 아니기 때문에 완벽히 정리된 내용은 아닙니다.
글이 매우 깁니다!! 제 코드보다 여러분들의 시간이 몇 배는 더 중요하다는 사실을 잊지 마세요.
목차
1. 프로젝트 목표 및 선행연구(?)
2. 데이터셋 분석
2.1. 데이터셋의 문제점
2.2 데이터 정제 및 전처리 과정
3. 데이터 시각화(1)
3.1. 선그래프: 시간대별 이용자수 분석
3.2. 출근시간과 퇴근시간 정의하기
4. 데이터 시각화(2)
4.1. 막대그래프: 출퇴근 시간 상위 20개 역
4.2. Folium 라이브러리 소개
4.3. 지도를 통한 시각화: 출퇴근 지하철역 혼잡도
5. 결론 및 시사점
5.1. 막대그래프와 지도를 통한 시각화 비교
6. 2호선 데이터 추가분석
6.1. 2호선 데이터 분석 과정
6.2. 분석 결과
1. 프로젝트 목표 및 선행연구
: 출퇴근 시간 중 서울 및 수도권의 지하철 혼잡도 분석
이를 지도에 표시하여 출퇴근 시간 지하철역 이용자수를 지리적으로 시각화하는 것,
즉 위치정보를 포함한 출퇴근 시간대에서의 지하철 혼잡도 시각화가 이번 프로젝트의 목표입니다.
선행연구라고 할만한 건 없지만,
학교에서 진행하는 엔지니어 양성교육 중 받은 자료의 코드를 활용하여 프로젝트를 진행하였습니다.
궁금하신 분들은 밑에 url로 들어가보시면 자세히 나와 있습니다.
https://marinadb.tistory.com/21
python으로 지하철 승하차 인원 데이터 분석해보기~!
본 게시물은 2021 NIPA AI 온라인 elice교육을 듣고 작성한 글입니다. 프로젝트 목표 승차 또는 하차 시 해당 시간, 해당 역의 승객 수를 확인하기 위해 개찰구 통과 승객 수 데이터와 지하철 위치좌
marinadb.tistory.com
2. 데이터셋 분석
서울시에서 제공한 지하철 이용자 수 데이터를 이용하였습니다.
https://data.seoul.go.kr/dataList/OA-12252/S/1/datasetView.do
열린데이터광장 메인
데이터분류,데이터검색,데이터활용
data.seoul.go.kr
이는 지속적으로 업데이트되며, 이번 데이터분석에서는 가장 최근 데이터인 2024년 12월 한 달 간의 데이터를 사용하였습니다. (최초 작성일 기준입니다^^)
## 데이터 불러오기
import pandas as pd
df = pd.read_csv("서울시 지하철 호선별 역별 시간대별 승하차 인원 정보.csv", encoding='euc-kr')
# 2015년부터 2024년 12월까지의 데이터 중, 2024년 12월 데이터만을 이용
df = df[df['사용월']==202412]
2.1. 데이터셋의 문제점
서울시에서 제공한 데이터셋의 문제점은 다음과 같습니다.
- 신분당선의 데이터가 누락되어 있다. 이는 강남구에서의 주요 환승역인 신사역, 논현역, 강남역, 양재역의 데이터가 실제오는 차이가 있을 수 있음을 의미한다.
- 1호선 주요 역들의 데이터가 누락되어 있다.
위 두 문제의 경우 데이터 제공 자체가 어려운 부분으로, 별다른 해결 없이 넘어가도록 하겠습니다.
- 지하철역을 '호선명'으로 먼저 나누기 때문에, 환승역의 경우 호선별로 데이터가 처리되어 있다. 예를 들어, 2호선과 3호선의 환승역인 교대역의 경우, csv 파일에서 '2호선 교대역'과 '3호선 교대역'의 데이터가 별개의 행으로 존재한다.
위의 문제를 해결하기 위해 판다스의 groupby 를 활용하여, 환승역에서 이용인원을 모두 더하였습니다.

2.2. 데이터 정제 및 전처리 과정
사실상 제공된 데이터셋에 그 어떤 결측치도, 이상치도 존재하지 않았기에 데이터 전처리는 거의 진행하지 않았습니다. 데이터 정제랄 것도 없고 주어진 데이터셋에 대한 최소한의 정리만 진행하였습니다.
데이터 분석의 편의성을 위하여 일일 평균 이용자수를 구한 후 상위 50개 행에 대해서만 분석을 진행하였습니다.

3. 데이터 시각화(1)
3.1. 선그래프: 시간대별 이용자수 분석
이후의 문제는 '출근시간'과 '퇴근시간'을 어떻게 정의할 것이냐는 문제였습니다.
이를 위해 각 시간대별 평균 승하차 인원을 계산한 후, 이 시계열 데이터(Time-Series Data)를 선그래프로 그렸습니다.
3.2. 출근시간과 퇴근시간 정의하기
이 선그래프에서 가장 높은 값을 가지는 시간 간격을 각각 출근시간과 퇴근시간으로 정의합니다.
위의 그래프에 의해 출근시간은 8시-10시, 퇴근시간은 17시-19시로 설정하였습니다.
정한 출퇴근 시간에 따른 데이터프레임을 새롭게 만들어줍니다
# 출근시간과 퇴근시간의 데이터셋을 각각 df1, df2로 저장한다.
df1 = pd.concat([df_top50.iloc[:,0], df_top50.iloc[:,9:13]], axis=1)
df2 = pd.concat([df_top50.iloc[:,0], df_top50.iloc[:,27:31]], axis=1)
df1['평균 이용자수'] = df1.iloc[:,1:].mean(axis=1).round()
df2['평균 이용자수'] = df2.iloc[:,1:].mean(axis=1).round()
4. 데이터 시각화(2)
4.1. 막대그래프: 출퇴근 시간 상위 20개 역
지도를 통한 시각화를 진행하기에 앞서 matplotlib을 통해 막대그래프로 출퇴근 시간 평균 이용자수 상위 20개 역을 시각화하여 보았습니다.
막대그래프 분석결과 출근시간과 퇴근시간 사이 상위 20개 지하철역이 다르다는 것과 출근시간보다 퇴근시간의 혼잡도(평균 이용자수)가 높다는 사실을 관찰할 수 있었습니다.
4.2. Folium 라이브러리 소개
데이터를 지도에 표시하기 위해서 Folium 라이브러리를 사용하였는데요,
Folium 라이브러리는 파이썬에서 대화형 지도(Interactive Map)을 생성하고, 데이터를 지도 위에 시각화할 수 있는 기능을 제공하는 라이브러리입니다.
대체 대화형 지도라는게 뭔소린가 했는데 그냥 Interactive Map의 직역이네요. 짧지만 잘 정리된 블로그 링크 첨부합니당
[python] 지도 라이브러리 Folium 사용기
※ 공부하는 포스팅으로 틀린 것이나 맞지 않는 표현 있을 수 있습니다. 피드백 받습니다!! python 지도 데이터 handling 위한 라이브러리 Folium의 기본적인 사용법 코드를 돌려보았다. python 라이브러
cow97.tistory.com
folium으로 지도에 위치를 표시하기 위해서는 각 지하철역의 위치 정보가 필요했습니다. 서울시에서 제공하는 데이터에는 각 지하철역의 위도 및 경도 정보가 담긴 데이터셋도 존재합니다.
https://data.seoul.go.kr/dataList/OA-21232/S/1/datasetView.do
열린데이터광장 메인
데이터분류,데이터검색,데이터활용
data.seoul.go.kr
이 데이터셋을 이용하여, 각 지하철역의 위도 및 경도 정보를 기존 데이터셋과 merge 하였습니다.
4.3. 지도를 통한 시각화: 출퇴근 지하철역 혼잡도
위에서 간단히 소개한 Folium 라이브러리를 통해 서울 및 수도권 지역의 지도를 호출한 뒤, 다음과 같은 코드를 통해 지도 위에 시각화를 진행해 보았습니다.
# folium 라이브러리를 통한 시각화
df1 = df1.dropna()
df2 = df2.dropna() # 위도 및 경도 데이터셋이 결측치인 행은 그냥 제거한다.
import folium
seoul = folium.Map(location=[37.5665, 126.9780], zoom_start=12)
for i in range(len(df1)): # 출근시간 빨간색으로 표시
marker = folium.CircleMarker(
[df1.iloc[i]['위도'], df1.iloc[i]['경도']],
radius=(df1.iloc[i]['평균 이용자수']/ 4000),
color='red',
fill=True,
fill_color='red'
)
marker.add_to(seoul)
for i in range(len(df2)): # 퇴근시간 파란색으로 표시
marker = folium.CircleMarker(
[df2.iloc[i]['위도'], df2.iloc[i]['경도']],
radius=(df2.iloc[i]['평균 이용자수']/ 4000),
color='blue',
fill=True,
fill_color='blue'
)
marker.add_to(seoul)
seoul
위의 코드를 간단히 설명하면, 출근시간은 빨간색, 퇴근시간은 파란색으로 표시하였고 원의 radius 설정은 '평균 이용자수/4000'으로 설정하였습니다.
밑의 사진은 출력값을 단순히 PrtSc한 것이고, 실제로 위의 코드를 돌려보시면 줌 및 이동이 가능한 실제 지도를 출력값으로 얻을 수 있습니다. (위에서 설명한 folium 라이브러리의 대화형 지도 제공)
folium 라이브러리는 객체를 HTML 형식으로 저장하는 기능도 지원합니다.
github의 Pages 를 통해 이 .html 파일을 url로 만들어내는 데에 성공하였습니다.(어려웠다)
밑의 링크로 들어가시면 위의 지도를 볼 수 있습니다.
https://powderblue210.github.io/test002/
..아 git 너무 어렵다
5. 결론 및 시사점
지도를 통하여 위치정보를 포함한 혼잡도를 시각화
:
막대그래프만으로는 위치정보 파악이 불가능하다.
이를 '출퇴근 시간대에서의 혼잡도'라는 프로젝트 목적에 부합하는 방식으로 시각화하려면 위치정보를 포함한 시각화를 진행하여야 한다.
이를 위해 folium 라이브러리를 사용하여, 지도에 혼잡도를 원의 크기로 나타내는 방식으로 시각화하였다.
막대그래프는 각 역의 이용자수만을 표시하는 반면, 지도의 경우 위치정보를 포함한 정보를 표시함으로서 '어느 지하철역'이 아닌, '어느 지역'에서의 지하철 혼잡도가 높게 나타나는지를 표시하며,
이는 서울시 전역에서의 지하철 이용에 대한 더욱 명확한 정보를 제공한다.
5.2. 막대그래프와 지도를 통한 시각화 비교
이번 프로젝트에서는 지하철 출퇴근 혼잡도를 막대그래프와 지도를 통한 두 방법으로 표현해 보았습니다. 이를 비교하여 얻은 결론들을 정리하면 다음과 같습니다.
- 두 경우 모두에서, 퇴근시간의 지하철 이용자수가 출근시간의 지하철 이용자수보다 전체적으로 높다는 것을 확인할 수 있다.
- 그러나 막대그래프에서는 단순한 이용객수만 파악 가능하다. 막대그래프로만 봤을 때, 사람들이 가장 몰리는 곳은 서울역과 잠실역이라고 판단할 수 있겠으나, 지도를 참고한다면 실제로 사람들이 많이 몰리는 구간은
① 서울시 중구의 서울역-종로-을지로 구간과 ② 서울시 강남구의 2호선 교대-강남-선릉 라인
이라고 볼 수 있다. - 데이터셋에서 1호선 주요역인 노량진-신도림-구로 구간의 데이터가 빠져 있으므로, 실제 서울시 영등포구, 구로구의 지하철 이용자수는 시각화한 데이터보다 많을 것이다.
또 하나 재밌는 사실은 홍대입구역의 경우 출근시간(8시-10시)에 비해 퇴근시간(17시-19시) 이용객 수가 월등히 높다는 사실입니다.
나는 아침부터 수업들으러 가는 데를 사람들은 왜 저녁에 놀러들 오는지 모르겠네요.
6. 2호선 데이터 추가 분석
6.1. 2호선 데이터 분석 과정
지도를 참고하면, 출퇴근 시간 이용객수가 많은 지하철역 중 대다수가 2호선임을 알 수 있습니다. 이러한 사실을 토대로 2호선에 대한 출퇴근 시간대(8시-10시, 17시-19시)의 데이터를 추가적으로 분석하였습니다.
import folium
seoul = folium.Map(location=[37.5665, 126.9780], zoom_start=12)
for i in range(len(line2)):
marker = folium.CircleMarker(
[line2.iloc[i]['위도'], line2.iloc[i]['경도']],
radius=(line2.iloc[i]['평균 이용자수']/ 4000),
color='green',
fill=True,
fill_color='green'
)
marker.add_to(seoul)
seoul
6.2. 분석 결과
2호선 데이터를 토대로, 지도에
① 상위 50개 지하철역 출근시간 데이터(빨간색)
② 상위 50개 지하철역 퇴근시간 데이터(파란색)
③ 2호선 지하철역의 출퇴근시간 데이터(초록색)
를 모두 표시해 보았습니다.
import folium
seoul = folium.Map(location=[37.5665, 126.9780], zoom_start=12)
for i in range(len(df1)): # 출근시간 빨간색으로 표시
marker = folium.CircleMarker(
[df1.iloc[i]['위도'], df1.iloc[i]['경도']],
radius=(df1.iloc[i]['평균 이용자수']/ 4000),
color='red',
fill=True,
fill_color='red'
)
marker.add_to(seoul)
for i in range(len(df2)): # 퇴근시간 파란색으로 표시
marker = folium.CircleMarker(
[df2.iloc[i]['위도'], df2.iloc[i]['경도']],
radius=(df2.iloc[i]['평균 이용자수']/ 4000),
color='blue',
fill=True,
fill_color='blue'
)
marker.add_to(seoul)
for i in range(len(line2)): # 2호선 초록색으로 표시
marker = folium.CircleMarker(
[line2.iloc[i]['위도'], line2.iloc[i]['경도']],
radius=(line2.iloc[i]['평균 이용자수']/ 4000),
color='green',
fill=True,
fill_color='green'
)
marker.add_to(seoul)
seoul
세 데이터를 모두 포함한 지도 데이터를 참고하면,
예상한 내용과 같이, 주요 지하철역(특히 잠실역, 홍대입구역, 강남역, 사당역 등) 에서 2호선 이용자수가 차지하는 부분이 상당하다는 사실을 알 수 있습니다.
데이터 크기를 원의 크기에 반영하여 표현하였기 때문에, 이와 같은 사실을 한눈에 시각적으로 파악 가능합니다.
이를 통해 출퇴근 시간 혼잡도가 높은 지하철역 이용자 대부분이 2호선을 이용한다는 결론을 도출 가능합니다.
2호선 데이터를 포함한 지도 또한 html 파일로 저장하여 url로 변환해 보았습니다.
https://powderblue210.github.io/test002/about.html
이거 git에서 동일한 repository에서 about.html로 저장한건데
아이거 아무리생각해도 이렇게하는거 아닌거같은데 저도 이 이상은 몰?루겠어요
참고) 오 비슷한거 한 사람 찾음..
데이터분석(빅데이터) : 지하철 이용객 분석
목적: 서울 지하철의 직원을 효율적으로 배치하기 위해 데이터 분석을 통하여 언제, 어디에 승객들이 가장 ...
blog.naver.com
제 코드는 코랩에 올려놨긴 했는데 그냥 기록용이니까 굳이 들어가서 보진 마세요오....ㅎ
https://colab.research.google.com/drive/1ZPI0yKy0vfFbbhkE1z8sEIz1io7JOIW5?usp=sharing
지하철 이용자수 분석.ipynb
Colab notebook
colab.research.google.com
소감 등등..
항상 느끼는 거지만, 코드를 써내려가는 과정보다 '목표 설정 과정+결론 및 시사점 도출 과정'이 가장 어려운 것 같습니다. 특히 결론 도출 과정은, 내가 쓴 코드 및 프로젝트 진행 과정에만 집중하느라, 시각화까지 다 해놓고선 혼자서는 제대로 된 결론을 도출 못하는 경우가 많습니다. 팀 프로젝트를 진행하거나 데이터 분석 결과를 제3자에게 보여주는 게 가장 좋을듯
다행인 점은, 지난 프로젝트(Bank Marketing 데이터셋 분석)에 비해 조금 더 내가 잘 알고있는(그리고 생활과 밀접한) 데이터를 이용했기 때문에, 지난 프로젝트에 비해서는 결론 도출이 쉬웠다는 점입니다.
또, 처음 보는 데이터셋이 주어졌을 때 어떤 방법으로 시각화하는 것이 적절할지 정하는 과정 또한 중요하다는 것을 알게 되었습니다. 만약 참고할 만한 코드가 없었다면, 혼자서 '지하철 이용객 수 데이터셋'을 '지도를 통해 위치정보를 포함해 시각화'하는 방법을 떠올릴 수 없었을 것 같아요.
그리고 데이터 분석이라고는 했는데, 너무 시각화에만 집중한 듯.. 전처리 좀 더 공부해 올게여
그리고 git은 진짜..하나도 모르겠음..
이상.
긴 글 읽어주셔서 감사합니다.
'데이터분석' 카테고리의 다른 글
[데이터분석] Titanic 데이터셋 (2): 시각화 & 피쳐 엔지니어링 (1) | 2025.02.25 |
---|---|
[데이터분석] Titanic 데이터셋 (1): 결측치 처리 (0) | 2025.02.24 |