- 개요
굳이 분석해보지 않아도 설날에는 서울 교통량이 줄어든다고 느끼실겁니다.
그럼 자동차가 배출하는 CO(일산화탄소), NO2(이산화질소)는 줄어들겠죠?
이번 포스트에서는 서울에서 정말로 설날에 교통량이 줄어드는지, 줄어든다면 얼마나 줄어드는지
그리고 설날에는 자동차 배출물질인 CO, NO2 농도가 얼마나 변하는지 확인하려고 합니다.
아래의 세 주제로 글을 연재합니다.
1. 서울 교통량 자료 수집 및 정제
2. 대기오염물질 자료 수집 및 정제
3. 설날기간의 서울 교통량, 대기오염물질 시계열 확인 및 해석
- 교통량 자료 수집
1. 서울 교통량 자료 다운로드
서울 교통량 자료는 '서울시 교통정보 시스템(TOPIS)' 홈페이지에서 다운로드 받습니다.
자료는 https://topis.seoul.go.kr/refRoom/openRefRoom_2.do 이 링크에서 받을 수 있습니다.

참고로 2015년은 양식이 달라서 2016년부터 2024년까지 다운로드 받겠습니다.
또한, 설날기간만 확인할 것이므로 1, 2월 자료만 받습니다.
전 손으로 일일히 클릭해서 받았지만 python으로 웹크롤링 하는 식으로 자동 다운로드 코드를 작성해도 될 것 같습니다(그냥 손으로 하는 게 더 빠를듯).
2. 자료의 기본 구조
교통량 자료의 확장자는 excel입니다.
좀 예전 파일은 엑셀파일의 sheet가 1개고, 최근 파일은 엑셀파일의 sheet의 수가 여러개입니다.
그리고 엑셀파일 sheet가 2개 이상일 때는 2번째 sheet에 교통량 자료가 있습니다.
이를 고려하여 교통량 자료를 읽어봅시다.
import os
inpath = './data/교통량'
fnlist = os.listdir(inpath)
import pandas as pd
dfs = []
for fn in fnlist:
excel_file = pd.ExcelFile(f'{inpath}/{fn}')
if len(excel_file.sheet_names) >= 2:
df = pd.read_excel(f'{inpath}/{fn}', sheet_name=1) # 엑셀시트가 2개 일 때 2번째 페이지를 읽음
else:
df = pd.read_excel(f'{inpath}/{fn}')
print(df.columns)
dfs.append(df)
df = pd.concat(dfs).reset_index(drop=True)
자료의 칼럼 이름을 확인해보면 아래와 같이 나옵니다.
Index(['일자', '요일', '지점명', '지점번호', '구분', '방향', '0시', '1시', '2시', '3시', '4시', '5시', '6시', '7시', '8시', '9시', '10시', '11시', '12시', '13시', '14시', '15시', '16시', '17시', '18시', '19시', '20시', '21시', '22시', '23시'], dtype='object')
여기서 우리가 필요한 열의 이름은 설날이 아닌지 구분하기 위한 '일자',
실제 자료가 들어있는 '0시~23시',
마지막으로 자료 정제를 위해 '지점번호'입니다.
참고로 지점번호별 교통량 측정소 위치는 아래의 그림과 같습니다(TOPIS에 있는 사진).

3. 자료 정제
학술적인 분석이 아니기 때문에 정말 간단한 정제작업만 하겠습니다.
2016년 1월 1일부터 2024년 2월 29일까지 자료가 존재하고, 결측치가 5% 이하인 교통량 관측지점만 분석합니다.
2016년에서 2024년까지 1월, 2월의 날짜수는 534일이지만 도로에는 상행/하행선(도로의 방향이 2개라 같은 장소여도 2개의 관측)이 있으므로 길이가 2배인 1068이어야 모든 날짜별 자료가 있는 것입니다.
마지막으로 위의 기준에 부합하는 지점만 csv 파일로 저장하겠습니다.
df['datetime'] = pd.to_datetime(df['일자'], format='%Y%m%d') # 나중에 datetime 형식을 써야하므로 미리 만듦
stn_num = df['지점번호'].unique().tolist() # 자료에 있는 지점번호 추출
stn_target = [] # 모든 날짜 자료가 있는 지점번호만 저장
for num in stn_num:
length_time = df['datetime'][df['지점번호']==num]
if len(length_time) == 1068:
stn_target.append(num)
cols = [f'{i}시' for i in range(0, 23+1)] # 0시, 1시..., 23시 열에 교통량 자료가 저장되어있음
stn_list = []
for num in stn_target:
value = df[cols][df['지점번호']==num]
missing_count = value.isna().sum().sum() # 결측치 수
if (missing_count / value.size <= 0.05): # 결측치 5% 이하
stn_list.append(num)
# 전체기간 자료가 있고, 결측치 5% 이하 관측소만 따로 추출하여 저장
df2 = df[df['지점번호'].isin(stn_list)].reset_index(drop=True)
df2.to_csv('seoul_traffic.csv')
앞으로 교통량을 분석할 땐 'seoul_traffic.csv' 파일을 읽어서 분석합니다.
참고로 지점번호별 교통량 관측소의 위도, 경도 자료가 있으면 좋겠는데 찾을 수가 없네요.
나중에 제가 만들든지 해야겠습니다.
그럼 다음 연재에선 대기오염물질 자료 수집 및 정제를 해보겠습니다.