import pandas as pd
import numpy as np
import folium
import pyproj
!pip install xlrd
import xlrd
Requirement already satisfied: xlrd in /root/00_PRJ/blog_group/quarto/gabrielwithappy.github.io/.venv/lib/python3.8/site-packages (2.0.1)
초등학교 근처는 교통사고를 예방책이 잘 준비되어 있을까? ### Target Audiance 초등학교 학부모, 학생들
### 필요한 데이터 분석 - 초등학교 위치 정보 - 초등학생 교통사고 유형 정보 - 초등학교 근처 교통 특징 정보 - 위험 요소 : 횡단보도, 공사장, ?? - 안전 요소 : 과속방지 CCTV, 과속 방지턱, 엘로우카펫 교통사고 예방방법 종류 ### 가설 설정 교통사고 예방방법이 많이 적용된 초등학교는 안전하다. 초등학생에게 자주 발생하는 교통사고를 분석하면 초등학교에 필요한 예방방법을 예측할 수 있다. 초등학교 근처의 교통 특징을 보면 교통사고 위험도를 알 수 있다 ### 데이터 - 횡단보도 : 서울특별시_교통안전시설물 횡단보도 정보 - 학교위치 및 기본정보 : 학교위치 및 기본정보 - 교통사고 다발 어린이보호구역 : ???
Requirement already satisfied: xlrd in /root/00_PRJ/blog_group/quarto/gabrielwithappy.github.io/.venv/lib/python3.8/site-packages (2.0.1)
df_summary_grade = pd.read_excel('./학년별_스쿨존내_어린이(12세이하)_보행_사상자_2023.xls')
df_summary_grade= df_summary_grade.rename(columns={'기준년도':'사고유형'})
df_summary_grade = df_summary_grade.melt('사고유형', value_vars=['1학년', '2학년', '3학년', '4학년', '5학년', '6학년'])
df_summary_grade= df_summary_grade.rename(columns={'variable':'학년'})
df_summary_grade_sum = df_summary_grade.groupby('학년')['value'].sum().to_frame()
df_summary_grade_sum= df_summary_grade_sum.reset_index()
import plotly.graph_objects as go
import plotly.express as px
fig = px.bar(df_summary_grade_sum, x='학년', y='value', title='상권분석 그래프', orientation='v')#, template='seaborn')
fig.show()
df_summary_behavior = pd.read_excel('./행동유형별_스쿨존내_어린이(12세이하)_보행_사상자.xls', header=1)
df_summary_behavior = df_summary_behavior.dropna()
_loop = df_summary_behavior.columns
_loop = _loop.drop(['합계'])
_loop
df_summary_behavior = df_summary_behavior.melt(id_vars = '기준년도', value_vars=_loop)
df_summary_behavior
df_summary_behavior= df_summary_behavior.rename(columns={'variable':'행동유형'})
df_summary_behavior = df_summary_behavior.reset_index()
df_summary_behavior
df_summary_behavior_sum = df_summary_behavior.groupby('행동유형')['value'].sum().to_frame()
df_summary_behavior_sum= df_summary_behavior_sum.reset_index()
df_summary_behavior_sum
fig = px.bar(df_summary_behavior_sum, x='행동유형', y='value', title='상권분석 그래프', orientation='v')#, template='seaborn')
fig.show()
/tmp/ipykernel_4713/3039976074.py:1: DtypeWarning:
Columns (17,18,19,24,25) have mixed types. Specify dtype option on import or set low_memory=False.
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 121553 entries, 0 to 121552
Data columns (total 28 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 횡단보도관리번호 121553 non-null object
1 상태 (공통) 121545 non-null float64
2 횡단보도종류코드 121544 non-null float64
3 가로길이 90355 non-null float64
4 세로길이 90355 non-null float64
5 화살표시수량 110303 non-null float64
6 화살표시길이 102943 non-null float64
7 고가 (공통) 121544 non-null float64
8 구경찰서코드 (공통) 121366 non-null float64
9 구코드 (공통) 120826 non-null float64
10 동코드 (공통) 121251 non-null float64
11 지번 119588 non-null object
12 신경찰서코드 (공통) 121516 non-null float64
13 작업구분 (공통) 121553 non-null int64
14 표출구분 (공통) 121553 non-null int64
15 도로구분 (공통) 120606 non-null float64
16 관할사업소 (공통) 120704 non-null float64
17 신규정규화ID 38800 non-null object
18 설치일 18101 non-null object
19 교체일 18196 non-null object
20 공간데이터 0 non-null float64
21 이력ID 121553 non-null int64
22 공사관리번호 115919 non-null object
23 구횡단보도관리번호 120897 non-null object
24 공사형태 (공통) 108876 non-null object
25 교차로코드 21820 non-null object
26 X좌표 121538 non-null float64
27 Y좌표 121538 non-null float64
dtypes: float64(16), int64(3), object(9)
memory usage: 26.0+ MB
횡단보도관리번호 0
상태 (공통) 0
횡단보도종류코드 0
가로길이 1598
세로길이 1598
화살표시수량 716
화살표시길이 963
고가 (공통) 0
구경찰서코드 (공통) 19
구코드 (공통) 0
동코드 (공통) 0
지번 65
신경찰서코드 (공통) 0
작업구분 (공통) 0
표출구분 (공통) 0
도로구분 (공통) 22
관할사업소 (공통) 20
신규정규화ID 3348
설치일 4127
교체일 4128
공간데이터 5216
이력ID 0
공사관리번호 144
구횡단보도관리번호 228
공사형태 (공통) 580
교차로코드 4283
X좌표 1
Y좌표 1
dtype: int64
횡단보도관리번호 | 상태 (공통) | 횡단보도종류코드 | 가로길이 | 세로길이 | 화살표시수량 | 화살표시길이 | 고가 (공통) | 구경찰서코드 (공통) | 구코드 (공통) | ... | 설치일 | 교체일 | 공간데이터 | 이력ID | 공사관리번호 | 구횡단보도관리번호 | 공사형태 (공통) | 교차로코드 | X좌표 | Y좌표 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 06-0000030030 | 1.0 | 2.0 | 0.0 | 0.0 | 4.0 | 1.0 | 1.0 | 390.0 | 380.0 | ... | NaN | NaN | NaN | 101702 | 2008-1108-025 | 06-030030 | 1 | NaN | 192679.8948 | 559453.6699 |
2 | 06-0000030054 | 1.0 | 2.0 | 0.0 | 0.0 | 0.0 | 1.0 | 1.0 | 390.0 | 380.0 | ... | NaN | NaN | NaN | 37033 | 2000-0000-000 | 06-030054 | NaN | NaN | 194094.3509 | 559522.4508 |
2 rows × 28 columns
Index(['횡단보도관리번호', '상태 (공통)', '횡단보도종류코드', '가로길이', '세로길이', '화살표시수량', '화살표시길이',
'고가 (공통)', '구경찰서코드 (공통)', '구코드 (공통)', '동코드 (공통)', '지번', '신경찰서코드 (공통)',
'작업구분 (공통)', '표출구분 (공통)', '도로구분 (공통)', '관할사업소 (공통)', '신규정규화ID', '설치일',
'교체일', '공간데이터', '이력ID', '공사관리번호', '구횡단보도관리번호', '공사형태 (공통)', '교차로코드',
'X좌표', 'Y좌표'],
dtype='object')
상태 (공통) | 횡단보도종류코드 | 가로길이 | 세로길이 | 화살표시수량 | 화살표시길이 | 고가 (공통) | 구경찰서코드 (공통) | 구코드 (공통) | 동코드 (공통) | 신경찰서코드 (공통) | 작업구분 (공통) | 표출구분 (공통) | 도로구분 (공통) | 관할사업소 (공통) | 공간데이터 | 이력ID | X좌표 | Y좌표 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 121530.000000 | 121529.000000 | 90340.000000 | 90340.000000 | 110288.000000 | 102928.000000 | 121529.000000 | 121351.000000 | 120811.000000 | 121236.000000 | 121501.000000 | 121538.000000 | 121538.000000 | 120591.000000 | 120689.000000 | 0.0 | 121538.000000 | 1.215380e+05 | 1.215380e+05 |
mean | 1.024726 | 2.060710 | 6.942860 | 3.709852 | 1.753228 | 1.573877 | 1.000963 | 267.391781 | 435.255564 | 11050.876802 | 265.532547 | 2.687530 | 1.329658 | 1.424824 | 106.509582 | NaN | 63782.338108 | 1.986829e+05 | 5.490437e+05 |
std | 0.264539 | 0.696957 | 7.478536 | 4.011229 | 1.730277 | 1.508579 | 0.039005 | 83.155851 | 188.132717 | 1809.472691 | 86.032718 | 1.461307 | 0.470091 | 0.494318 | 1.668715 | NaN | 40836.244467 | 1.269200e+04 | 2.642661e+04 |
min | 1.000000 | 1.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | 1.000000 | 110.000000 | 110.000000 | 0.000000 | 110.000000 | 1.000000 | 1.000000 | 1.000000 | 104.000000 | NaN | 1.000000 | -1.200176e+04 | 5.100000e+01 |
25% | 1.000000 | 2.000000 | 0.000000 | 0.000000 | 0.000000 | 1.000000 | 1.000000 | 200.000000 | 290.000000 | 10300.000000 | 190.000000 | 1.000000 | 1.000000 | 1.000000 | 105.000000 | NaN | 30402.250000 | 1.926279e+05 | 5.457116e+05 |
50% | 1.000000 | 2.000000 | 0.000000 | 0.000000 | 2.000000 | 1.000000 | 1.000000 | 270.000000 | 440.000000 | 10600.000000 | 270.000000 | 4.000000 | 1.000000 | 1.000000 | 107.000000 | NaN | 60864.500000 | 2.002344e+05 | 5.499873e+05 |
75% | 1.000000 | 2.000000 | 15.000000 | 8.000000 | 4.000000 | 1.000000 | 1.000000 | 340.000000 | 590.000000 | 11300.000000 | 340.000000 | 4.000000 | 2.000000 | 2.000000 | 108.000000 | NaN | 91264.750000 | 2.047577e+05 | 5.537566e+05 |
max | 4.000000 | 6.000000 | 15.000000 | 35.000000 | 42.000000 | 20.000000 | 3.000000 | 410.000000 | 740.000000 | 18700.000000 | 410.000000 | 6.000000 | 2.000000 | 2.000000 | 109.000000 | NaN | 159620.000000 | 1.474722e+06 | 1.179377e+06 |
# proj1 = pyproj.Proj(init='epsg:8165')
# proj2 = pyproj.Proj(init='epsg:4326')
# fx, fy = pyproj.transform(proj1, proj2, df['X좌표'], df['Y좌표'])
def project_array(coord, p1_type, p2_type):
"""
좌표계 변환 함수
- coord: x, y 좌표 정보가 담긴 NumPy Array
- p1_type: 입력 좌표계 정보 ex) epsg:5179
- p2_type: 출력 좌표계 정보 ex) epsg:4326
"""
p1 = pyproj.Proj(init=p1_type)
p2 = pyproj.Proj(init=p2_type)
fx, fy = pyproj.transform(p1, p2, coord[:, 0], coord[:, 1])
return np.dstack([fx, fy])[0]
array([[192679.8948, 559453.6699],
[194094.3509, 559522.4508],
[189576.5582, 553775.811 ],
...,
[192699.5937, 545494.7748],
[190746.1785, 545409.8107],
[192708.2449, 545502.1187]])
p1_type = "epsg:5186"
p2_type = "epsg:4326"
# project_array() 함수 실행
result = project_array(coord, p1_type, p2_type)
df['경도'] = result[:, 0]
df['위도'] = result[:, 1]
df.head()
df
df_loc = df[['횡단보도관리번호', '상태 (공통)' ,'신규정규화ID', '이력ID', '공사관리번호', '구코드 (공통)','위도', '경도']]
df_loc_guro = df_loc[df_loc['구코드 (공통)'] == 530]
df_loc_guro
/root/00_PRJ/blog_group/quarto/gabrielwithappy.github.io/.venv/lib/python3.8/site-packages/pyproj/crs/crs.py:141: FutureWarning:
'+init=<authority>:<code>' syntax is deprecated. '<authority>:<code>' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6
/root/00_PRJ/blog_group/quarto/gabrielwithappy.github.io/.venv/lib/python3.8/site-packages/pyproj/crs/crs.py:141: FutureWarning:
'+init=<authority>:<code>' syntax is deprecated. '<authority>:<code>' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6
/tmp/ipykernel_4713/2905416754.py:14: FutureWarning:
This function is deprecated. See: https://pyproj4.github.io/pyproj/stable/gotchas.html#upgrading-to-pyproj-2-from-pyproj-1
/tmp/ipykernel_4713/4265179734.py:6: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
/tmp/ipykernel_4713/4265179734.py:7: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
횡단보도관리번호 | 상태 (공통) | 신규정규화ID | 이력ID | 공사관리번호 | 구코드 (공통) | 위도 | 경도 | |
---|---|---|---|---|---|---|---|---|
173 | 06-0000005482 | 1.0 | 1152694 | 33837 | 2008-0112-847 | 530.0 | 37.488290 | 126.858558 |
182 | 06-0000005553 | 1.0 | NaN | 2287 | 2000-0000-000 | 530.0 | 37.502715 | 126.862302 |
523 | 06-0000029865 | 1.0 | NaN | 40287 | 2010-0108-038 | 530.0 | 37.483324 | 126.841663 |
524 | 06-0000029865 | 1.0 | NaN | 67482 | 2010-0108-038 | 530.0 | 37.483175 | 126.841876 |
525 | 06-0000029865 | 1.0 | NaN | 72274 | 2010-0108-038 | 530.0 | 37.483175 | 126.841876 |
... | ... | ... | ... | ... | ... | ... | ... | ... |
121442 | 06-0000054175 | 1.0 | 1154231.0 | 159505 | NaN | 530.0 | 37.494838 | 126.856403 |
121456 | 06-0000054176 | 1.0 | 1154232.0 | 159506 | NaN | 530.0 | 37.494730 | 126.856263 |
121458 | 06-0000006482 | 1.0 | 2107192.0 | 31834 | 2004-0108-210 | 530.0 | 37.510976 | 126.884303 |
121501 | 06-0000041080 | 1.0 | 2131078.0 | 110540 | NaN | 530.0 | 37.482978 | 126.900314 |
121505 | 06-0000029242 | 1.0 | NaN | 33251 | 2000-0000-000 | 530.0 | 37.495085 | 126.858776 |
5215 rows × 8 columns
from folium.plugins import HeatMap
import branca.colormap as cm
from collections import defaultdict
center = [37.53165351203043, 126.9974246490573]
tiles = "http://mt0.google.com/vt/lyrs=m&hl=ko&x={x}&y={y}&z={z}"
m = folium.Map(location=center, tiles= tiles, attr="Google", zoom_start =14)
colormap = cm.LinearColormap(colors=[ 'red', 'yellow','blue', 'green'], vmin=0, vmax=100)
colormap.caption = 'HeatMap Intensity'
# 1. Draw SafeZone (HeatMap)
df_raw_safezone = pd.read_csv('어린이보호구역_위치도.csv', encoding='cp949')
df_raw_safezone.rename(columns={'x좌표':'경도', 'y좌표':'위도'}, inplace = True)
_df_safezone = df_raw_safezone[['위도', '경도']].copy()
_df_safezone.loc[:,'value'] = 100
for _, row in _df_safezone.iterrows():
lat, lon = row['위도'], row['경도']
folium.Circle(location=[lat, lon], tooltip='safezone', color='lightgreen', fill=True ).add_to(m)
# 2. Draw CCTV
df_raw_cctv = pd.read_csv('서울시_강남구_어린이보호구역.csv', encoding='cp949')
df_raw_cctv = df_raw_cctv.dropna(subset=['위도','경도', 'CCTV설치대수'])
_df_cctv = df_raw_cctv[['위도', '경도', 'CCTV설치대수']].copy()
_df_cctv.rename(columns={'CCTV설치대수':'value'}, inplace = True)
_df_cctv.head(3)
for _, row in _df_cctv.iterrows():
lat, lon = row['위도'], row['경도']
folium.Circle(location=[lat, lon], tooltip='cctv', color='green', fill=True).add_to(m)
# 4. Draw crosswalk
nosignal = 0.1
df_raw_crosswalk = pd.read_csv('서울특별시_성동구_횡단보도.csv', encoding='cp949')
df_raw_crosswalk.rename(columns={'X좌표(경도)':'경도', 'Y좌표(위도)':'위도'}, inplace = True)
df_raw_crosswalk.head(1)
df_raw_crosswalk = df_raw_crosswalk[['위도','경도','보행자신호등 유무']]
df_raw_crosswalk.loc[:,'value'] = df_raw_crosswalk['보행자신호등 유무'].replace({'N':nosignal, 'Y':0})
df_crosswalk = df_raw_crosswalk[['위도', '경도', 'value']]
display(df_crosswalk)
for _, row in df_crosswalk.iterrows():
lat, lon = row['위도'], row['경도']
if row['value'] == nosignal:
folium.CircleMarker(location=[lat, lon], tooltip='신호등 없는 횡단보도', max_level=13, color='red', redius=1, fill=True, fill_opacity=0.1, opacity=0).add_to(m)
# Draw HeatMap
_df_heatmap = pd.concat([_df_safezone, _df_cctv])
_df_heatmap_negative = df_crosswalk
_df_heatmap = _df_heatmap
HeatMap(_df_heatmap.values.tolist(),
radius = 20,
blur=20,
min_opacity=0.5,
# max_zoom=5,
gradient = {0:'red', 0.25:'yellow',0.5:'blue', 0.9:'lightgreen', 1:'green'} ).add_to(m)
colormap.add_to(m)
# HeatMap(_df_heatmap_negative.values.tolist(),
# radius = 5,
# blur=20,
# min_opacity=0.5,
# # max_zoom=5,
# gradient = {1:'red'} ).add_to(m)
# colormap.add_to(m)
# 1. Draw School
df_element_raw = pd.read_csv('./element_info.csv')
_df_school = df_element_raw.dropna(subset=['위도','경도'])
for _, row in _df_school.iterrows():
lat, lon = row['위도'], row['경도']
folium.Circle(location=[lat, lon], popup=row['학교명'], color='black', fill=True ).add_to(m)
m
위도 | 경도 | value | |
---|---|---|---|
0 | 37.561306 | 127.035717 | 0.0 |
1 | 37.562108 | 127.033961 | 0.1 |
2 | 37.562864 | 127.032547 | 0.0 |
3 | 37.562930 | 127.032486 | 0.1 |
4 | 37.544121 | 127.063398 | 0.0 |
... | ... | ... | ... |
982 | 37.544061 | 127.057766 | 0.1 |
983 | 37.543682 | 127.059001 | 0.1 |
984 | 37.543254 | 127.060418 | 0.1 |
985 | 37.545279 | 127.061395 | 0.1 |
986 | 37.545704 | 127.059941 | 0.1 |
987 rows × 3 columns