3 분 소요

ABC 부트캠프 [2021 지역별 사망 교통사고 데이터 분석 및 시각화]

image

팀과제로 교수님이 2021년 지역별로 사망교통사고 데이터 분석을 하라고 하셨다.

10개조가 나와서 조장들이 분석할 지역을 정하는 시간이었는데

하기 전에 난 우리 조원들에게 다들 어디 출신이냐고 물어봤다

6명중 2명이 대전 사람, 2명이 대구 사람, 각각 다른 지역 사람이라서

대전은 해봤으니 그럼 대구로 해야지~ 했는데

눈앞에서 다른 조 조장이던 내 친구에게 빼앗겼다

그래도 딱 생각나는 지역이 인천광역시가 떠올라서

우리 10조는 인천광역시의 데이터를 분석하기로 하였다.

[팀과제] 2021년 지역별 사망 교통사고 데이터 분석하기

  1. 어느 지역이 가장 많은 사망 교통사고가 발생 했었나
  2. 어느 시간대에 가장 많은 사망 교통사고가 발생 했었나
  3. 교통사고 정보를 지도에 표시하여 시각화

패키지 설치 및 라이브러리 임포트

pip install koreanize-matplotlib
import pandas as pd
import plotly.express as px
import seaborn as sns
import matplotlib.pyplot as plt
import koreanize_matplotlib

import folium

데이터 준비

  • 도로교통공단_사망 교통사고 정보_20211231.csv
df = pd.read_csv('/content/도로교통공단_사망 교통사고 정보_20211231.csv', encoding='EUC-KR')
df

image

데이터 전처리

df.info()
# 발생년월일시는 문자열(object)이라 따로 타입변경을 안해줘도 된다

image

# 발생년월일시 -> 발생시간(int)
df['발생년월일시'] = pd.to_datetime(df['발생년월일시'])

# 1) 발생시간
df['발생시간'] = df['발생년월일시'].dt.hour

# 2) 발생년월일
df['발생년월일'] = pd.to_datetime(df['발생년월일시'].dt.strftime('%Y-%m-%d'))

# 3) 결과 확인
df.info()

image

to_datetime을 사용하여 데이터 타입만 변경하게 하였고,

dt.hour을 사용해서 시간만 문자열 %Y-%m-%d 형태로 추출하게 하였다.

필요없는 컬럼 삭제 및 컬럼 정렬

del df['발생년월일시']    # 컬럼삭제
df.info()

image

발생년월일시가 삭제된 것을 알 수 있다.

# 컬럼명을 리스트로 만들기
col1 = df.columns[-2:].to_list()    # 마지막 컬럼 두개(발생시간/발생년월일) 선택
col1.reverse()                      # 리스트를 역순으로 뒤집는다
col2 = df.columns[1:-2].to_list()    # 두번째 컬럼부터 마지막에서 두 번째 컬럼까지를 선택(발생년제외)
col_list = col1 + col2
col_list.insert(0, '발생년')      # 0번째에 발생년 삽입

# 원하는 컬럼 순서대로 추출
df = df[col_list]
Index(['발생년', '발생년월일', '발생시간', '주야', '요일', '사망자수', '부상자수', '중상자수', '경상자수',
       '부상신고자수', '발생지시도', '발생지시군구', '사고유형_대분류', '사고유형_중분류', '사고유형', '가해자법규위반',
       '도로형태_대분류', '도로형태', '가해자_당사자종별', '피해자_당사자종별', '발생위치X(UTMK)',
       '발생위치Y(UTMK)', '경도', '위도'],
      dtype='object')
df.info()

image

정제된 데이터셋 저장하기

df.to_csv('2021년 지역별 교통사고 데이터 전처리.csv', encoding='utf-8-sig', index=False)    # 데이터셋 다운로드

인천광역시 교통사고 발생 데이터 분석

데이터 준비

ich_df = df[df['발생지시도']=='인천']    # ich_df라는 인천 데이터값 할당
ich_df.info()

전국별 교통사고 발생

location_list = df['발생지시도'].unique()    # 정렬할 때 사용
location_list.sort()

plt.figure(figsize=(10,5))     # figure로 크기 조정
sns.countplot(data=df, x='발생지시도', order=location_list)
plt.show()    # 인천은 전국에서 11등

image

시간대 별 교통사고 사망자 현황

fig = px.bar(ich_df, x='사망자수', y='발생시간', orientation='h')
fig.show()
# 인천은 가장 많은 사망 교통사고가 새벽 6시에 발생한다
# 그 이유는 아마 인천은 인천국제공항이 있고, 화물 운송 차량들이 많아 화물을 운송하는
# 새벽 6시가 가장 많을 것이라고 예상한다

image

새벽 6시가 가장 많은 이유가 아마 화물 운송 차량들이 많아

운송할 때 발생하는 교통사고가 크게 기여했을 것이라고 예상한다.

fig = px.pie(ich_df, names='발생시간', values='사망자수' )
fig.update_traces(textposition='inside', textinfo='percent+label')
fig.show()

image

요일별 교통사고 사망자 현황

fig = px.bar(df, x='사망자수', y='요일', orientation='h', category_orders={'요일': ['월', '화', '수', '목', '금', '토', '일']})
fig.show()
# 전국에서 가장 많은 사망 교통사고가 목요일에 발생한다

image

전국은 목요일에 많이 발생하지만,

fig = px.bar(ich_df, x='사망자수', y='요일', orientation='h', category_orders={'요일': ['월', '화', '수', '목', '금', '토', '일']})
fig.show()
# 인천은 가장 많은 사망 교통사고가 수요일에 발생한다

image

인천은 수요일에 많이 발생한다.

수요일에 더 교통사고가 발생할까라는 추측은 해외 배송에서 수요일에 통관하기 때문에

통관일정의 이유가 제일 크지 않을까 한다.

지역구별 교통사고 사망자 현황

fig = px.bar(ich_df, x='사망자수', y='발생지시군구', orientation='h')
fig.show()
# 인천은 서구에서 가장 많은 사망 교통사고가 발생한다
# 중구는 인구가 적은데도 왜 교통사고 사망자가 2위일까?
# 남동구와 부평구는 인구가 많은데도, 서구에 비해 상대적으로 교통사고 사망자가 적은 이유

image

image

중구는 인원이 적은데 사망 교통사고 2위에 해당한다.

그 이유는 아마 중구에 인천국제공항이 있기 때문

사고유형별 교통사고 사망자 현황

fig = px.bar(ich_df, x='사망자수', y='사고유형', orientation='h')
fig.show()
# 인천은 가장 많은 사망 교통사고가 횡단중일 때 가장 많이 발생한다

image

지도를 활용하여 교통사고 현황 분석

import folium

map = folium.Map(location=[36.35041119, 127.3845475]) # 경도, 위도

인천광역시 사망교통사고 위치 지도 시각화

# 사망사고 위치에 CircleMarker 표출
# CircleMarker 사이즈 =  사망자수 + 경상자수
# CircleMarker 클릭하면, popup으로 사고유형 나타나도록 구현

# CircleMarker 사이즈(radius) -> 실수형 데이터만 취급
# 사망자수, 경상자수 컬럼 데이터타입 -> 실수형으로 변경
ich_df = ich_df.astype({'사망자수':'float', '경상자수':'float'})
ich_df.head()

image

사망자수+경상자수에 따른 CircleMarker 지도에 표출

# 1) 지도 준비
map = folium.Map(location=[37.4562557, 126.7052062]) # 경도, 위도

# 인천국제공항 핀 추가
crd = {"lat": float(37.4692), "lng": float( 126.451)}

folium.Marker([crd['lat'], crd['lng']],
              icon = folium.Icon(color = 'blue', icon = 'plane', prefix = 'fa')).add_to(map)


# 2) CircleMarker 지도에 표출 -> for문을 이용해서 ich_df 데이터가 있을때까지 CicleMarker 지도에 add
for n in ich_df.index:
  # CircleMarker size -> cnt
  cnt = ich_df['사망자수'][n] + ich_df['경상자수'][n]

  # 위도, 경도 추출
  lat = ich_df['위도'][n]
  lng = ich_df['경도'][n]

  # CircleMarker 지도에 add
  folium.CircleMarker([lat, lng], radius=cnt*8, popup=ich_df['사고유형'][n],   # radius로 Circle이 더 크게 그려짐
                      color='#0067A3', fill_color='#0067A3').add_to(map)

map

image

인천광역시 사망교통사고 지도 시각화 저장

map.save('2021_인천교통사고현황.html')

우리조 조장 조원 모두 완벽해서 . . 발표도 잘한 것 같아 뿌듯하다!

댓글남기기