프로젝트 개요
-
분석 목적
- 1. 광진구의 주차 문제 해결을 위한 새로운 방안 필요
- 2. 공공데이터를 활용하여 광진구의 주차 문제 파악 및 정책 제시
-
분석 배경
- 1. 광진구에서는 공영주차장과 무료주차장을 운영하고 있고, 광진구 주민들을 위한 주차장이 마련되어 있다. 하지만 아파트 단지나 상가 등에서 주차 공간이 부족한 경우가 많아 무단 주정차 문제가 발생한다.
- 2. 무단 주차는 교통을 방해하고, 법적 문제가 발생하므로, 광진구의 안전하고 원활한 교통 환경을 만들어 나갈 수 있도록 해당 문제의 분석 및 해결이 필요하다.
-
분석 내용
1. 광진구 전체 주정차 단속 현황
2. 광진구 행정동별 주정차 단속 현황
3. 광진구 행정동별 단속 CCTV 효용 비교
4. 광진구 행정동별 주차장 활용도 비교
5. 광진구 행정동별 주정차 단속 건수 비교 -
인사이트
- 1. 주민들이 불편을 겪는 가장 큰 문제는 교통소통장애, 보도, 주차금지구역에서의 불법 주정차 문제이다.
- 2. 불법 주정차 문제 해결이 가장 시급한 지역은 구의동(구의1동, 구의3동), 자양동(동일로20길), 중곡동(중곡역, 용마도시자연공원)이다.
- 3. 주차장 근처에 불법 주정차가 집중된 것을 확인했다. 이는 불법 주정차 발생 이유가 주차면이 부족하기 때문이다.
- 4. 특히 불법 주정차가 많이 발생하는 원인을 주변의 쇼핑센터, 공원, 역 근처 등에서 찾을 수 있었다.
- Category
- Period
- GitHub
지역 데이터 분석 | |
2023.03.20.~2023.05.04. | |
https://github.com/Isaac-Seungwon/gwangjin-parking-analysis |
데이터 불러오기
from google.colab import files
uploaded = files.upload()
# Saving 서울특별시 광진구 주정차 단속 현황 (2022년).csv to 서울특별시 광진구 주정차 단속 현황 (2022년).csv
from google.colab import files
uploaded = files.upload()
# Saving 서울특별시 광진구 주정차 단속 현황 (2023년).csv to 서울특별시 광진구 주정차 단속 현황 (2023년).csv
from google.colab import files
uploaded = files.upload()
# Saving 2022 광장동.csv to 2022 광장동.csv
from google.colab import files
uploaded = files.upload()
# Saving 2022 구의동.csv to 2022 구의동.csv
from google.colab import files
uploaded = files.upload()
# Saving 2022 능동.csv to 2022 능동.csv
from google.colab import files
uploaded = files.upload()
# Saving 2022 자양동.csv to 2022 자양동.csv
from google.colab import files
uploaded = files.upload()
# Saving 2022 군자동.csv to 2022 군자동.csv
from google.colab import files
uploaded = files.upload()
# Saving 2022 중곡동.csv to 2022 중곡동.csv
from google.colab import files
uploaded = files.upload()
# Saving 2022 화양동.csv to 2022 화양동.csv
from google.colab import files
uploaded = files.upload()
# Saving 서울특별시 광진구 주정차 단속 CCTV 위치 정보.csv to 서울특별시 광진구 주정차 단속 CCTV 위치 정보.csv
from google.colab import files
uploaded = files.upload()
# Saving 서울특별시 광진구 공영주차장 정보.csv to 서울특별시 광진구 공영주차장 정보.csv
!pip install geopy
!pip install geopandas
# 데이터 분석과 시각화를 위한 라이브러리 및 모듈 import
import pandas as pd
import numpy as np
import seaborn as sns
import glob
import plotly.graph_objects as go
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.patches as patches
import folium
from folium import plugins
from folium.plugins import MarkerCluster, HeatMap
import geopy
from geopy.geocoders import Nominatim
# 지오코딩을 위한 Nominatim 객체를 생성하고, user_agent를 'South Korea'로 설정
geo_local = Nominatim(user_agent='South Korea')
# 추가적인 라이브러리 및 모듈 import
import requests
import json
import os
import math
import time
import geopandas as gpd
import folium
import matplotlib.pyplot as plt
# 지리 정보를 다루기 위한 라이브러리 import
from shapely.geometry import mapping, shape, Point, Polygon, LineString
각각 '서울특별시 광진구 주정차 단속 현황 (2022년).csv', '서울특별시 광진구 주정차 단속 현황 (2023년).csv', '2022 광장동.csv', '2022 구의동.csv', '2022 능동.csv', '2022 자양동.csv', '2022 군자동.csv', '2022 중곡동.csv', '2022 화양동.csv', '서울특별시 광진구 주정차 단속 CCTV 위치 정보.csv', '서울특별시 광진구 공영주차장 정보.csv' 파일을 업로드한다.
한글 폰트 깨짐 현상 해결
# 실행 후 > 런타임 (런타임 다시 시작) > 다시 실행
!sudo apt-get install -y fonts-nanum # 나눔 폰트 설치
!sudo fc-cache -fv # 폰트 캐시 갱신
!rm ~/.cache/matplotlib -rf # Matplotlib 캐시 제거
plt.rc('font', family = 'NanumBarunGothic') # 한글 폰트 설정
주정차 단속 데이터 불러오기 (2023년)
Parking_Crackdown_2023_df = pd.read_csv('서울특별시 광진구 주정차 단속 현황 (2023년).csv', encoding = 'cp949')
CCTV_df = pd.read_csv('서울특별시 광진구 주정차 단속 CCTV 위치 정보.csv', encoding = 'cp949')
Public_Parking_Lot_df = pd.read_csv('서울특별시 광진구 공영주차장 정보.csv', encoding = 'cp949')
동별 데이터 불러오기 (2022년)
Gwangjangdong_df = pd.read_csv('2022 광장동.csv', encoding = 'cp949')
Guuidong_df = pd.read_csv('2022 구의동.csv', encoding = 'cp949')
Gunjadong_df = pd.read_csv('2022 군자동.csv', encoding = 'cp949')
Neungdong_df = pd.read_csv('2022 능동.csv', encoding = 'cp949')
Jayangdong_df = pd.read_csv('2022 자양동.csv', encoding = 'cp949')
Junggokdong_df = pd.read_csv('2022 중곡동.csv', encoding = 'cp949')
Hwayangdong_df = pd.read_csv('2022 화양동.csv', encoding = 'cp949')
2022년 단속 데이터 확인
Parking_Crackdown_2022_df.head()

2023년 단속 데이터 확인
Parking_Crackdown_2023_df.head()

CCTV 데이터 확인
CCTV_df.head()

공영주차장 데이터 확인
Public_Parking_Lot_df.head()

주소 데이터 전처리
# 주소 데이터 전처리 함수 정의
def get_addrs(x):
x1 = x.split(' ')
return " ".join(x1[2:4])
# '단속장소' 컬럼에 전처리 함수 적용
Parking_Crackdown_2022_df['단속장소'] = Parking_Crackdown_2022_df['단속장소'].apply(get_addrs)
# 전처리된 결과 출력
Parking_Crackdown_2022_df

'단속장소' 컬럼에서 주소를 추출하여 전처리하는 작업을 수행한다. 주소는 공백을 기준으로 분리되며, 앞 부분에 위치한 불필요한 정보를 제거한 뒤, 남은 주소를 다시 합쳐서 업데이트한다.
위도 경도 변환
# 경도 반환 함수
def geocoding_lon(address):
try:
geo = geo_local.geocode(address)
return geo.longitude
except:
return 0
# 위도 반환 함수
def geocoding_lat(address):
try:
geo = geo_local.geocode(address)
return geo.latitude
except:
return 0
# 데이터프레임에 위도와 경도 추가
Parking_Crackdown_2022_df['위도'] = Parking_Crackdown_2022_df['단속장소'].apply(geocoding_lat)
Parking_Crackdown_2022_df['경도'] = Parking_Crackdown_2022_df['단속장소'].apply(geocoding_lon)
Parking_Crackdown_2022_df
경도 반환 함수 (geocoding_lon): 입력된 주소에 대한 geopy 라이브러리의 geocode 함수를 이용하여 해당 주소의 위치 정보를 받아온다. 위치 정보에서 경도 (longitude)를 반환하며, 주소가 잘못되거나 위치 정보를 얻을 수 없는 경우에는 0을 반환한다.
위도 반환 함수 (geocoding_lat): 입력된 주소에 대한 geopy 라이브러리의 geocode 함수를 이용하여 해당 주소의 위치 정보를 받아온다. 위치 정보에서 위도 (latitude)를 반환하며, 주소가 잘못되거나 위치 정보를 얻을 수 없는 경우에는 0을 반환한다.
'단속장소' 컬럼의 주소 정보를 이용하여 해당 장소의 위도와 경도를 구하는 함수를 정의하고, 이를 데이터프레임에 적용하여 '위도' 및 '경도' 컬럼을 추가하는 작업을 수행한다.
데이터프레임에 위도와 경도 추가하여 '단속장소' 컬럼의 각 행에 대해 위도와 경도를 구하는 함수를 적용한다. 그리고 '위도' 및 '경도' 컬럼을 새로 추가하고, 각 행에 대해 위도와 경도를 계산하여 저장한다.
Geocoding 함수
def geocoding(address):
geolocoder = Nominatim(user_agent = 'South Korea', timeout = None)
geo = geolocoder.geocode(address)
crd = {
"lat": str(geo.latitude),
"lng": str(geo.longitude)
}
return crd
crd = geocoding("서울 광진구 구의사거리")
print(crd['lat'])
print(crd['lng'])
Nominatim: 입력된 주소의 위도(lat)와 경도(lng)를 반환하는 함수이다.
예시 주소fh "서울 광진구 구의사거리"에 대한 위도와 경도를 출력한다.
Folium 라이브러리를 사용하여 지도를 생성하고, 해당 지도에 마커 및 클러스터를 추가하는 작업을 수행한다.
주차 위반내용에 따른 지도에 마커 추가
map4 = folium.Map(location = [37.552, 127.085], zoom_start = 14)
for i in Parking_Crackdown_2023_df.index:
name = Parking_Crackdown_2023_df.loc[i, '위반내용']
lat = Parking_Crackdown_2023_df.loc[i, '위도']
lon = Parking_Crackdown_2023_df.loc[i, '경도']
if Parking_Crackdown_2023_df['위반내용'][i] == '교통소통장애':
code_color = 'orange'
elif Parking_Crackdown_2023_df['위반내용'][i] == '보도':
code_color = 'green'
elif Parking_Crackdown_2023_df['위반내용'][i] == '도로모퉁이':
code_color = 'blue'
else: code_color = 'black'
marker = folium.Marker([lat, lon], popup = name, icon = folium.Icon(color = code_color)).add_to(map4)
map4
Parking_Crackdown_2023_df의 주차 위반내용에 따라 마커를 다르게 표시한다.
'교통소통장애', '보도', '도로모퉁이'에 따라 각각 다른 색상의 마커를 사용한다.
CCTV 위치 및 주차 데이터 지도에 표시
map5 = folium.Map(location = [37.552, 127.085], zoom_start = 14)
for i in CCTV_df.index:
name2 = CCTV_df.loc[i, '단속지점명']
lat2 = CCTV_df.loc[i, '위도']
lon2 = CCTV_df.loc[i, '경도']
code_color = 'red'
marker = folium.Marker([lat2,lon2], popup = name2, icon = folium.Icon(color = code_color)).add_to(map5)
marker_cluster = MarkerCluster().add_to(map5)
for lat, long in zip(Parking_Crackdown_2023_df.위도, Parking_Crackdown_2023_df.경도):
folium.Marker([lat, long]).add_to(marker_cluster)
map5
CCTV_df의 위치와 Parking_Crackdown_2023_df의 주차 데이터를 지도에 표시한다.
CCTV는 빨간색 마커로, 주차 데이터는 클러스터를 이용하여 표시한다.
공영주차장, CCTV, 주차 데이터 지도에 표시
map5 = folium.Map(location = [37.552, 127.085], zoom_start = 14)
for i in Public_Parking_Lot_df.index:
name1 = Public_Parking_Lot_df.loc[i, '시설명']
lat1 = Public_Parking_Lot_df.loc[i, '위도']
lon1 = Public_Parking_Lot_df.loc[i, '경도']
code_color = 'green'
marker = folium.Marker([lat1, lon1], popup = name1, icon = folium.Icon(color = code_color, icon = 'flag')).add_to(map5)
for i in CCTV_df.index:
name2 = CCTV_df.loc[i, '단속지점명']
lat2 = CCTV_df.loc[i, '위도']
lon2 = CCTV_df.loc[i, '경도']
code_color = 'red'
marker = folium.Marker([lat2, lon2], popup = name2, icon = folium.Icon(color = code_color, icon = 'star')).add_to(map5)
marker_cluster = MarkerCluster().add_to(map5)
for lat, long in zip(Parking_Crackdown_2023_df.위도, Parking_Crackdown_2023_df.경도):
folium.CircleMarker([lat, long], radius = 5).add_to(marker_cluster)
map5
공영주차장, CCTV, 주차 데이터를 지도에 표시하며, 각각 다른 아이콘 및 스타일로 표시한다.
공영주차장은 초록색 깃발(icon='flag'), CCTV는 빨간색 별(icon='star'), 주차 데이터는 클러스터를 이용하여 표시한다.
광장동
map5 = folium.Map(location = [37.552, 127.085], zoom_start = 14)
for i in Public_Parking_Lot_df.index:
name1 = Public_Parking_Lot_df.loc[i, '시설명']
lat1 = Public_Parking_Lot_df.loc[i, '위도']
lon1 = Public_Parking_Lot_df.loc[i, '경도']
code_color = 'green'
marker = folium.Marker([lat1, lon1], popup = name1, icon = folium.Icon(color = code_color, icon = 'flag')).add_to(map5)
for i in CCTV_df.index:
name2 = CCTV_df.loc[i, '단속지점명']
lat2 = CCTV_df.loc[i, '위도']
lon2 = CCTV_df.loc[i, '경도']
code_color = 'red'
marker = folium.Marker([lat2, lon2], popup = name2, icon = folium.Icon(color = code_color, icon = 'star')).add_to(map5)
marker_cluster = MarkerCluster().add_to(map5)
for i in Gwangjangdong_df.index:
name = Gwangjangdong_df.loc[i, '위반내용']
lat = Gwangjangdong_df.loc[i, '위도']
lon = Gwangjangdong_df.loc[i, '경도']
marker = folium.CircleMarker([lat, lon], popup = name, icon = folium.Icon(color = code_color)).add_to(map5)
for lat, long in zip(Gwangjangdong_df.위도, Gwangjangdong_df.경도):
folium.CircleMarker([lat, long], radius = 5).add_to(marker_cluster)
map5
'광장동'에 대한 지도를 생성하며, 공영주차장, CCTV, 주차 데이터를 각각 다른 스타일로 표시한다.
'광장동'의 경우 주차 데이터는 다양한 색상의 원(CircleMarker)으로 표시한다.
구의동
map5 = folium.Map(location = [37.552, 127.085], zoom_start = 14)
for i in Public_Parking_Lot_df.index:
name1 = Public_Parking_Lot_df.loc[i, '시설명']
lat1 = Public_Parking_Lot_df.loc[i, '위도']
lon1 = Public_Parking_Lot_df.loc[i, '경도']
code_color = 'green'
marker = folium.Marker([lat1,lon1], popup=name1, icon=folium.Icon(color=code_color, icon = 'flag')).add_to(map5)
for i in CCTV_df.index:
name2 = CCTV_df.loc[i, '단속지점명']
lat2 = CCTV_df.loc[i, '위도']
lon2 = CCTV_df.loc[i, '경도']
code_color = 'red'
marker = folium.Marker([lat2,lon2], popup = name2, icon = folium.Icon(color = code_color, icon = 'star')).add_to(map5)
marker_cluster = MarkerCluster().add_to(map5)
for i in Guuidong_df.index:
name = Guuidong_df.loc[i, '위반내용']
lat = Guuidong_df.loc[i, '위도']
lon = Guuidong_df.loc[i, '경도']
marker = folium.CircleMarker([lat,lon], popup=name, icon=folium.Icon(color=code_color)).add_to(map5)
for lat, long in zip(Guuidong_df.위도, Guuidong_df.경도):
folium.CircleMarker([lat, long], radius = 5).add_to(marker_cluster)
map5
군자동
map5 = folium.Map(location = [37.552, 127.085], zoom_start = 14)
for i in Public_Parking_Lot_df.index:
name1 = Public_Parking_Lot_df.loc[i, '시설명']
lat1 = Public_Parking_Lot_df.loc[i, '위도']
lon1 = Public_Parking_Lot_df.loc[i, '경도']
code_color = 'green'
marker = folium.Marker([lat1,lon1], popup=name1, icon=folium.Icon(color=code_color, icon = 'flag')).add_to(map5)
for i in CCTV_df.index:
name2 = CCTV_df.loc[i, '단속지점명']
lat2 = CCTV_df.loc[i, '위도']
lon2 = CCTV_df.loc[i, '경도']
code_color = 'red'
marker = folium.Marker([lat2,lon2], popup = name2, icon = folium.Icon(color = code_color, icon = 'star')).add_to(map5)
marker_cluster = MarkerCluster().add_to(map5)
for i in Gunjadong_df.index:
name = Gunjadong_df.loc[i, '위반내용']
lat = Gunjadong_df.loc[i, '위도']
lon = Gunjadong_df.loc[i, '경도']
marker = folium.CircleMarker([lat,lon], popup=name, icon=folium.Icon(color=code_color)).add_to(map5)
for lat, long in zip(Gunjadong_df.위도, Gunjadong_df.경도):
folium.CircleMarker([lat, long], radius = 5).add_to(marker_cluster)
map5
능동
map5 = folium.Map(location = [37.552, 127.085], zoom_start = 14)
for i in Public_Parking_Lot_df.index:
name1 = Public_Parking_Lot_df.loc[i, '시설명']
lat1 = Public_Parking_Lot_df.loc[i, '위도']
lon1 = Public_Parking_Lot_df.loc[i, '경도']
code_color = 'green'
marker = folium.Marker([lat1,lon1], popup=name1, icon=folium.Icon(color=code_color, icon = 'flag')).add_to(map5)
for i in CCTV_df.index:
name2 = CCTV_df.loc[i, '단속지점명']
lat2 = CCTV_df.loc[i, '위도']
lon2 = CCTV_df.loc[i, '경도']
code_color = 'red'
marker = folium.Marker([lat2,lon2], popup = name2, icon = folium.Icon(color = code_color, icon = 'star')).add_to(map5)
marker_cluster = MarkerCluster().add_to(map5)
for i in Neungdong_df.index:
name = Neungdong_df.loc[i, '위반내용']
lat = Neungdong_df.loc[i, '위도']
lon = Neungdong_df.loc[i, '경도']
marker = folium.CircleMarker([lat,lon], popup=name, icon=folium.Icon(color=code_color)).add_to(map5)
for lat, long in zip(Neungdong_df.위도, Neungdong_df.경도):
folium.CircleMarker([lat, long], radius = 5).add_to(marker_cluster)
map5
자양동
map5 = folium.Map(location = [37.552, 127.085], zoom_start = 14)
for i in Public_Parking_Lot_df.index:
name1 = Public_Parking_Lot_df.loc[i, '시설명']
lat1 = Public_Parking_Lot_df.loc[i, '위도']
lon1 = Public_Parking_Lot_df.loc[i, '경도']
code_color = 'green'
marker = folium.Marker([lat1,lon1], popup=name1, icon=folium.Icon(color=code_color, icon = 'flag')).add_to(map5)
for i in CCTV_df.index:
name2 = CCTV_df.loc[i, '단속지점명']
lat2 = CCTV_df.loc[i, '위도']
lon2 = CCTV_df.loc[i, '경도']
code_color = 'red'
marker = folium.Marker([lat2,lon2], popup = name2, icon = folium.Icon(color = code_color, icon = 'star')).add_to(map5)
marker_cluster = MarkerCluster().add_to(map5)
for i in Jayangdong_df.index:
name = Jayangdong_df.loc[i, '위반내용']
lat = Jayangdong_df.loc[i, '위도']
lon = Jayangdong_df.loc[i, '경도']
marker = folium.CircleMarker([lat,lon], popup=name, icon=folium.Icon(color=code_color)).add_to(map5)
for lat, long in zip(Jayangdong_df.위도, Jayangdong_df.경도):
folium.CircleMarker([lat, long], radius = 5).add_to(marker_cluster)
map5
중곡동
map5 = folium.Map(location = [37.552, 127.085], zoom_start = 14)
for i in Public_Parking_Lot_df.index:
name1 = Public_Parking_Lot_df.loc[i, '시설명']
lat1 = Public_Parking_Lot_df.loc[i, '위도']
lon1 = Public_Parking_Lot_df.loc[i, '경도']
code_color = 'green'
marker = folium.Marker([lat1,lon1], popup=name1, icon=folium.Icon(color=code_color, icon = 'flag')).add_to(map5)
for i in CCTV_df.index:
name2 = CCTV_df.loc[i, '단속지점명']
lat2 = CCTV_df.loc[i, '위도']
lon2 = CCTV_df.loc[i, '경도']
code_color = 'red'
marker = folium.Marker([lat2,lon2], popup = name2, icon = folium.Icon(color = code_color, icon = 'star')).add_to(map5)
marker_cluster = MarkerCluster().add_to(map5)
for i in Junggokdong_df.index:
name = Junggokdong_df.loc[i, '위반내용']
lat = Junggokdong_df.loc[i, '위도']
lon = Junggokdong_df.loc[i, '경도']
marker = folium.CircleMarker([lat,lon], popup=name, icon=folium.Icon(color=code_color)).add_to(map5)
for lat, long in zip(Junggokdong_df.위도, Junggokdong_df.경도):
folium.CircleMarker([lat, long], radius = 5).add_to(marker_cluster)
map5
화양동
map5 = folium.Map(location = [37.552, 127.085], zoom_start = 14)
for i in Public_Parking_Lot_df.index:
name1 = Public_Parking_Lot_df.loc[i, '시설명']
lat1 = Public_Parking_Lot_df.loc[i, '위도']
lon1 = Public_Parking_Lot_df.loc[i, '경도']
code_color = 'green'
marker = folium.Marker([lat1,lon1], popup=name1, icon=folium.Icon(color=code_color, icon = 'flag')).add_to(map5)
for i in CCTV_df.index:
name2 = CCTV_df.loc[i, '단속지점명']
lat2 = CCTV_df.loc[i, '위도']
lon2 = CCTV_df.loc[i, '경도']
code_color = 'red'
marker = folium.Marker([lat2,lon2], popup = name2, icon = folium.Icon(color = code_color, icon = 'star')).add_to(map5)
marker_cluster = MarkerCluster().add_to(map5)
for i in Hwayangdong_df.index:
name = Hwayangdong_df.loc[i, '위반내용']
lat = Hwayangdong_df.loc[i, '위도']
lon = Hwayangdong_df.loc[i, '경도']
marker = folium.CircleMarker([lat,lon], popup=name, icon=folium.Icon(color=code_color)).add_to(map5)
for lat, long in zip(Hwayangdong_df.위도, Hwayangdong_df.경도):
folium.CircleMarker([lat, long], radius = 5).add_to(marker_cluster)
map5