import pandas as pd
import numpy as np
import folium
import pyproj
!pip install xlrd
import xlrdRequirement 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