| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- #abc부트캠프 #유클리드소프트 #고용노동부 #대한상공회의소 #미래내일일경험사업
- #abc 프로젝트 멘토링 #유클리드소프트 #고용노동부 #대한상공회의소 #미래내일일경험사업 #공부일지 #멘토링일지
- Today
- Total
나른한 코딩 생활
[9일차] ABC 부트캠프 도로교통공단 데이터로 종합적인 데이터 분석 본문
사실상 이번주차의 마지막 수업인 9일차가 다가왔다
익일 수업인 10일차에는 ESG 포럼& 세미나 강의를 듣기 때문에
파이썬 실습은 이번주차에 오늘이 마지막이라고 볼 수 있다
오늘은 도로교통공단 사망 교통사고 정보를 활용한 지역별 사망교통사고 분석해보자
밑작업
저번과 동일하게 먼저 데이터파일의 준비와 기본적인 install 및 import를 진행하겠다
!pip install koreanize-matplotlibpip
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import koreanize_matplotlib
import folium
import warnings
warnings.filterwarnings('ignore')
df = pd.read_csv('/content/도로교통공단_교통사고 정보_2019.csv',encoding='euc-kr')
df.info() # 불러온 데이터 확인
accident_df = df.copy()
accident_df.head()
accident_df.info() # 원본 데이터 복사 및 확인
기본적인 준비가 끝났으면 먼저 데이터를 전처리 하는 과정이 필요하다
# 사망 교통사고가 가장 많이 발생한 시간은>
# 발생년월일시 -> 시간 추출 -> 뒤에 두자리(00~23) -> 파생 컬럼으로 따로 분리
# 2019010121 -> 21 -> # 분리 할 수 있는 키워드 없음 -> 문자열 슬라이싱
# 1) 문자열 슬라이싱 하고 싶으면 문자열로 타입 변경
accident_df = accident_df.astype({'발생년월일시' : 'string'})
accident_df.info()
# 문자열 말고 % 100 연산으로 끝 뒤를 가져오는건 힘든가?
# -> 할 수 있음!! 여기서는 인덱스를 쓰는 방법을 사용할 뿐
# 2) 시간으로 분리한 데이터를 발생시간 컬럼에 담기
accident_df['발생시간'] = accident_df['발생년월일시'].str[-2:]
# 확인하면 마지막 컬럼 '발생시간'이 생성된 것을 파악 가능
accident_df['발생년월일'] = pd.to_datetime(accident_df['발생년월일시'].str[:-2],
format='%Y%m%d',errors='raise')
del accident_df['발생년월일시'] # 칼럼 삭제
accident_df.info()

위와 같이 '발생시간' 과 '발생년월일' 컬럼을 만들고 '발생년월일시' 컬럼을 삭제 했다
현재 accident_df 의 컬럼 정렬 상태를 원하는 형태로(파악하기 쉽게) 바꾸기 위해
아래와 같은 코드를 작성했다.
# 2) 컬럼 순서 정리 발생년, 발생년월일, 발생시간, ...
# 2-1) 컬럼명을 리스트로 만들기
col1 = accident_df.columns[-2:].to_list()
col1.reverse() # revers() 는 해당 리스트를 뒤집는다
col2 = accident_df.columns[1:-2].to_list()
col_list = col1 + col2
col_list.insert(0,'발생년')
# 2-2) 원하는 컬럼의 순서대로 추출 후 다시 담기
accident_df = accident_df[col_list]

이렇게 한 데이터파일을 새로운 파일로 저장하는 것도 가능하다
accident_df.to_csv('2019년 사망 교통사고 전처리_20240704.csv',
encoding = 'utf-8-sig', index=False)
날짜별/시간별 교통사고 현황
이번에는 날짜별/시간별 교통사고 현황 을 scatter를 사용해 출력해보자
fig = px.scatter(accident_df,x= '발생년월일',y='발생시간',
size = '사망자수',color='발생지시도')
fig.show()

시간대별 교통사고 사망자 현황
다음으로는 사망시간별 발생 사망자수를 출력한다
fig = px.bar(accident_df, x = '사망자수',y = '발생시간',orientation='h')
fig.show()

시도별 교통사고 사망자 현황
발생지역에 따른 사망자 현황을 조사해보자 지역 구분은 자치도와 광역시 크기로 나누었다.
accident_df['발생지시도'].unique()
# 먼저 같은 지역이 다른 명으로 기재되어 있는지 등
# 눈으로 데이터를 파악하는 과정이 꼭 필요하다
이렇게 확인 후 이상이 없으면 데이터 상의 지역들에 대한 리스트를 하나 생성한다
해당 변수의 이름은 location_list 라고 선언했다
location_list에 대한
location_list = accident_df['발생지시도'].unique() # 중복제거
location_list.sort() # 해당 리스트를 ㄱㄴㄷ 순으로 정렬
fig = px.bar(accident_df, x = '사망자수',y = '발생지시도',orientation='h',category_orders={'발생지시도':location_list})
fig.show()

fig = px.histogram(accident_df, x = '사망자수',y = '발생지시도',
orientation='h',text_auto=True,
category_orders={'발생지시도':accident_df['발생지시도'].value_counts().index})
fig.show() # 사건 발생건수로 히스토그램 출력

대전광역시 사망 교통사고 데이터 분석 및 시각화
앞서 했던 데이터 분석은 전체 데이터를 통해 지역 통합 데이터를 분석하였다
이번에는 특정 지역에 대한 사망 교통사고 데이터를 분석 및 시각화 해보도록 하겠다
현재 ABC 부트캠프 수업을 듣고 있는 대전광역시로 설정하였다
dj_df = accident_df.query("발생지시도 == '대전'")
dj_df 라는 데이터프레임은 복사한 데이터프레임에서 '발생지시도' 값이
'대전'인 데이터만 가져온 후 대입한 변수이다
이제부터는 지금까지 배운 내용을 이용하여 3가지의 주제로 그래프를 출력해보겠다
fig = px.bar(dj_df, x='사망자수',y='발생시간',
orientation='h')
fig.show()

fig = px.bar(dj_df, x='사망자수',y='발생지시군구',
orientation='h')
fig.show()

accident_df['발생월'] = accident_df['발생년월일'].dt.month
dj_df['발생월'] = dj_df['발생년월일'].dt.month
fig, axes = plt.subplots(1,2,figsize=(15,5))
plt.suptitle('2019년 월별 교통사고 발생건수 비교')
sns.countplot(data=accident_df,x='발생월',ax=axes[0],
order=accident_df['발생월'].value_counts().index)
axes[0].set_title('전국')
sns.countplot(data=dj_df,x='발생월',ax=axes[1],
order=dj_df['발생월'].value_counts().index)
axes[1].set_title('대전')
# 비교하는 차트의 y축 고정하기
plt.ylim(0,accident_df['발생월'].value_counts().max())
plt.show()

지도를 활용한 사고 현황 시각화
이번에는 지도를 활용하여 지도상에 마커를 찍어 교통사고 사망자료를 시각화 해보겠다
map = folium.Map(location=[36.321655, 127.378953])
위의 location 뒤 두가지의 실수형 값은 대전시청의 위도, 경도 값이다

이제 본격적으로 지도를 이용하여 사망사고 위치에 CircleMarker를 표출하도록 하겠다
CircleMarker의 사이즈는 총 사상자수를 의미하고
CircleMarker를 클릭하게 되면 popup 이벤트로 사고유형을 표출하도록 하겠다
# CircleMaker 사이즈는 실수형 데이터만 취급
# 사망자수, 부상자수 컬럼 자료형을 실수형으로 형변환
dj_df = dj_df.astype({'사망자수':'float','부상자수':'float'})
# 1) 지도 준비
map = folium.Map(location=[36.321655, 127.378953]) # 위도, 경도
# 2) CircleMarker 지도에 표출 -> for문을 이용해서 dj_df에 정보가 있을 때까지 지도에 add
for n in dj_df.index:
# CircleMarker의 사이즈
cnt = dj_df['사망자수'][n] + dj_df['부상자수'][n]
# 사고 위치 위도, 경도 추출
lat = dj_df['위도'][n]
lng = dj_df['경도'][n]
# 지도에 add 하기
folium.CircleMarker(location=[lat,lng],radius=cnt*10,
popup=dj_df['사고유형'][n], color='red',fill_color='red').add_to(map)
map

마지막으로 팀프로젝트로 진행했던 특정 구역을 지정한 후 해당 데이터셋을 분석하는 과정 중
내가 맡은 파트인 도로형태 분석을 보겠다
도로형태에 따른 사망자 비율을 파이차트로 표현
us_df = ac_df.query("발생지시도 == '울산'")
# 울산에 대한 데이터 프레임 us_df 생성
먼저 기존과 동일하게 전체 데이터 프레임인 ac_df 에서 ( 위 코드들의 accident_df 와 같음 )
발생지시도가 울산인 값만 us_df 라는 새로운 데이터 프레임에 저장
지난 시간에 성별 월급에 대한 평균통계를 구하는 sex_income 을 참고하여
RoadShape_income 을 구했다.
( 사실 변수명을 RoadShape_income 이 아닌 RoadShape_acc 로 해야했다... )
RoadShape_income = us_df.groupby('도로형태', as_index=False).agg(dead_sumby =('사망자수','sum'))

그럼 이제 이렇게 생성된 데이터셋을 px를 통해 파이차트로 나타내기만 하면 된다.
px.pie(RoadShape_income,names='도로형태',values='dead_sumby')

내일은 ESG 포럼 및 세미나 특강이 있다
아쉽게도 유성구까지 가야하기에 조기기상을 해야한다
내일 강연이 어떤 식으로 진행되는지는 모르지만 재밌다고 하니 기대된다
'ABC 부트캠프' 카테고리의 다른 글
| [11일차] ABC 부트캠프 데이터 크롤링 실전 (1) | 2024.07.09 |
|---|---|
| [10일차] ABC 부트캠프 ESG포럼&세미나 (0) | 2024.07.07 |
| [8일차] ABC 부트캠프 라이브러리를 통한 데이터 분석 (0) | 2024.07.03 |
| [7일차] ABC 부트캠프 공공데이터 활용 및 Pandas 라이브러리 (0) | 2024.07.03 |
| [6일차] ABC 부트캠프 데이터 시각화 (0) | 2024.07.01 |