티스토리 뷰

2단원 서울시 범죄 현황 분석 - 복사본

제 2장 서울시 범죄 현황 분석

구성 및 블로깅 진행과정

2-1 데이터 획득하기
2-2 pandas를 이용하여 데이터 정리하기
2-3 지도 정보를 얻을 수 있는 Google Maps
2-4 Google Maps를 이용해서 주소와 위도, 경도 정보 얻기
-------------------------------------------------------
2-5 pandas의 pivot_table 학습하기
2-6 pivot_table을 이용해서 데이터 정리하기
2-7 데이터 표현을 위해 다듬기
-------------------------------------------------------
2-8 좀 더 편리한 시각화 도구 - Seaborn
2-9 범죄 데이터 시각화하기
-------------------------------------------------------
2-10 지도 시각화 도구 - folium
2-11 서울시 범죄율에 대한 지도 시각화
2-12 서울시 경찰서별 검거율과 구별 범죄 발생율을 동시에 시각화하기

출처: 파이썬으로 데이터 주무르기 by 민형기

2-1 데이터 획득하기

서울시 공공 데이터 사이트인 data.go.kr에 접속하여 서울시 관서별 5대 범죄 현황이라는 글을 찾아 데이터를 다운 받을 수 있다.
또 다른 방법으로는 책 저자 민형기님의 깃허브 사이트https://github.com/PinkWink/DataScience/tree/master/data

  1. crime_in_Seoul.csv

을 다운받는다.

2-2 pandas를 이용하여 데이터 정리하기

In [1]:
import numpy as np
import pandas as pd
In [2]:
# 살인, 강도, 강간, 절도, 폭력이라는 5대 범죄에 대한 발생 건수와 검거 건수.
crime_anal_police = pd.read_csv('pydata/02. crime_in_Seoul.csv', thousands=',',
                                encoding='euc-kr')
crime_anal_police.head()
Out[2]:
관서명 살인 발생 살인 검거 강도 발생 강도 검거 강간 발생 강간 검거 절도 발생 절도 검거 폭력 발생 폭력 검거
0 중부서 2 2 3 2 105 65 1395 477 1355 1170
1 종로서 3 3 6 5 115 98 1070 413 1278 1070
2 남대문서 1 0 6 4 65 46 1153 382 869 794
3 서대문서 2 2 5 4 154 124 1812 738 2056 1711
4 혜화서 3 2 5 4 96 63 1114 424 1015 861

강남 3구가 안전한지 알아보고자 하는 것이 목표!!

데이터를 읽는 과정에서 주의해야 할 점

  • 데이터가 관서별로 되어있다. >> 경찰서 목록을 소속 구별로 변경하고 싶다.(경찰서 이름으로 구 정보를 알아야 한다.)
  • 서울시는 한 구에 하나 혹은 두 군데의 경찰서가 위치해 있다.
  • 구 이름과 경찰서 이름이 다른 경찰서도 있다.

2-3 지도 정보를 얻을 수 있는 Google Maps

Google Maps API에 접속하여 가입한다.(교육 목적으로 가입할 경우 1년 무료)
api 키가 발급되므로 키를 복사해서 준비한다.
터미널에 접속하여 pip install googlempas라는 명령어로 파이썬에 googlemaps를 사용할 수 있도록 설치한다.

2-4 Google Maps를 이용해서 주소와 위도, 경도 정보 얻기

In [3]:
#Googlempas를 import한다.
import googlemaps
In [4]:
# 자신의 api 키를 입력한다.
gmaps_key='**************************'
gmaps = googlemaps.Client(key=gmaps_key)
In [5]:
# Google Maps를 사용하여 '서울중부경찰서'를 검색해본다.
gmaps.geocode('서울중부경찰서', language='ko')
Out[5]:
[{'address_components': [{'long_name': '27',
    'short_name': '27',
    'types': ['premise']},
   {'long_name': '수표로',
    'short_name': '수표로',
    'types': ['political', 'sublocality', 'sublocality_level_4']},
   {'long_name': '을지로동',
    'short_name': '을지로동',
    'types': ['political', 'sublocality', 'sublocality_level_2']},
   {'long_name': '중구',
    'short_name': '중구',
    'types': ['political', 'sublocality', 'sublocality_level_1']},
   {'long_name': '서울특별시',
    'short_name': '서울특별시',
    'types': ['administrative_area_level_1', 'political']},
   {'long_name': '대한민국',
    'short_name': 'KR',
    'types': ['country', 'political']},
   {'long_name': '100-032',
    'short_name': '100-032',
    'types': ['postal_code']}],
  'formatted_address': '대한민국 서울특별시 중구 을지로동 수표로 27',
  'geometry': {'location': {'lat': 37.5636465, 'lng': 126.9895796},
   'location_type': 'ROOFTOP',
   'viewport': {'northeast': {'lat': 37.56499548029149,
     'lng': 126.9909285802915},
    'southwest': {'lat': 37.56229751970849, 'lng': 126.9882306197085}}},
  'place_id': 'ChIJc-9q5uSifDURLhQmr5wkXmc',
  'plus_code': {'compound_code': 'HX7Q+FR 대한민국 서울특별시',
   'global_code': '8Q98HX7Q+FR'},
  'types': ['establishment', 'point_of_interest', 'police']}]
  • 나중에 진행할 지도시각화에 유용한 정보
    formatted_address : 주소
    lng : 위도
    lat : 경도
In [6]:
#경찰서의 이름이 '수서서'와 같이 나타나 있으므로 '서울수서경찰서'와 같은 형태로 만들자

station_name=[]

for name in crime_anal_police['관서명']:
    station_name.append('서울' + str(name[:-1]) + '경찰서')
    
station_name
Out[6]:
['서울중부경찰서',
 '서울종로경찰서',
 '서울남대문경찰서',
 '서울서대문경찰서',
 '서울혜화경찰서',
 '서울용산경찰서',
 '서울성북경찰서',
 '서울동대문경찰서',
 '서울마포경찰서',
 '서울영등포경찰서',
 '서울성동경찰서',
 '서울동작경찰서',
 '서울광진경찰서',
 '서울서부경찰서',
 '서울강북경찰서',
 '서울금천경찰서',
 '서울중랑경찰서',
 '서울강남경찰서',
 '서울관악경찰서',
 '서울강서경찰서',
 '서울강동경찰서',
 '서울종암경찰서',
 '서울구로경찰서',
 '서울서초경찰서',
 '서울양천경찰서',
 '서울송파경찰서',
 '서울노원경찰서',
 '서울방배경찰서',
 '서울은평경찰서',
 '서울도봉경찰서',
 '서울수서경찰서']
In [7]:
# 이제 경찰서의 이름을 활용하여 주소를 받아올 수 있다.
station_address = []
station_lat = []
station_lng = []

for name in station_name:
    tmp = gmaps.geocode(name, language='ko')
    station_address.append(tmp[0].get('formatted_address')) # 경찰서 주소 추가
    
    tmp_loc = tmp[0].get('geometry')
    
    station_lat.append(tmp_loc['location']['lat']) # 경찰서 위치의 위도 추가
    
    station_lng.append(tmp_loc['location']['lng']) # 경찰서 위치의 경도 추가
    
    print(name + '-->' + tmp[0].get('formatted_address'))
서울중부경찰서-->대한민국 서울특별시 중구 을지로동 수표로 27
서울종로경찰서-->대한민국 서울특별시 종로구 종로1.2.3.4가동 율곡로 46
서울남대문경찰서-->대한민국 서울특별시 중구 회현동 한강대로 410
서울서대문경찰서-->대한민국 서울특별시 서대문구 충현동 통일로 113
서울혜화경찰서-->대한민국 서울특별시 종로구 인의동 창경궁로 112-16
서울용산경찰서-->대한민국 서울특별시 용산구 원효로1가 원효로89길 24
서울성북경찰서-->대한민국 서울특별시 성북구 삼선동5가 301
서울동대문경찰서-->대한민국 서울특별시 동대문구 청량리동 약령시로21길 29
서울마포경찰서-->대한민국 서울특별시 마포구 아현동 618-1
서울영등포경찰서-->대한민국 서울특별시 영등포구 영등포동 영등포로46길 14
서울성동경찰서-->대한민국 서울특별시 성동구 행당동 왕십리광장로 9
서울동작경찰서-->대한민국 서울특별시 동작구 노량진1동 노량진로 148
서울광진경찰서-->대한민국 서울특별시 광진구 구의동 자양로 167
서울서부경찰서-->대한민국 서울특별시 은평구 대조동 통일로 757
서울강북경찰서-->대한민국 서울특별시 강북구 번1동 오패산로 406
서울금천경찰서-->대한민국 서울특별시 금천구 시흥동 190
서울중랑경찰서-->대한민국 서울특별시 중랑구 신내1동 신내역로3길 40-10
서울강남경찰서-->대한민국 서울특별시 강남구 대치동 998
서울관악경찰서-->대한민국 서울특별시 관악구 봉천동
서울강서경찰서-->대한민국 서울특별시 양천구 신월동 화곡로 73
서울강동경찰서-->대한민국 서울특별시 강동구 성내1동 성내로 57
서울종암경찰서-->대한민국 서울특별시 성북구 종암동 종암로 135
서울구로경찰서-->대한민국 서울특별시 구로구 가마산로 235
서울서초경찰서-->대한민국 서울특별시 서초구 서초3동 반포대로 179
서울양천경찰서-->대한민국 서울특별시 양천구 신정6동 목동동로 99
서울송파경찰서-->대한민국 서울특별시 송파구 가락본동 9
서울노원경찰서-->대한민국 서울특별시 노원구 하계동 노원로 283
서울방배경찰서-->대한민국 서울특별시 서초구 방배본동 동작대로 204
서울은평경찰서-->대한민국 서울특별시 은평구 불광동 연서로 365
서울도봉경찰서-->대한민국 서울특별시 도봉구 창4동 노해로 403
서울수서경찰서-->대한민국 서울특별시 강남구 개포동 개포로 617
In [8]:
#주소
station_address[:5]
Out[8]:
['대한민국 서울특별시 중구 을지로동 수표로 27',
 '대한민국 서울특별시 종로구 종로1.2.3.4가동 율곡로 46',
 '대한민국 서울특별시 중구 회현동 한강대로 410',
 '대한민국 서울특별시 서대문구 충현동 통일로 113',
 '대한민국 서울특별시 종로구 인의동 창경궁로 112-16']
In [9]:
#위도
station_lat[:5]
Out[9]:
[37.5636465, 37.5755578, 37.5547584, 37.5647848, 37.5718529]
In [10]:
#경도
station_lng[:5]
Out[10]:
[126.9895796, 126.9848674, 126.9734981, 126.9667762, 126.9989143]
In [11]:
# 주소를 쪼갠다음 '구'가 들어있는 단어만 뽑아내어 '구별'이라는 컬럼에 추가해준다.
gu_name=[]

for name in station_address:
    tmp = name.split()
    
    tmp_gu = [gu for gu in tmp if gu[-1] == '구'][0]
    
    gu_name.append(tmp_gu)
    
crime_anal_police['구별'] = gu_name
crime_anal_police.head()
Out[11]:
관서명 살인 발생 살인 검거 강도 발생 강도 검거 강간 발생 강간 검거 절도 발생 절도 검거 폭력 발생 폭력 검거 구별
0 중부서 2 2 3 2 105 65 1395 477 1355 1170 중구
1 종로서 3 3 6 5 115 98 1070 413 1278 1070 종로구
2 남대문서 1 0 6 4 65 46 1153 382 869 794 중구
3 서대문서 2 2 5 4 154 124 1812 738 2056 1711 서대문구
4 혜화서 3 2 5 4 96 63 1114 424 1015 861 종로구

주의 : 금천경찰서의 경우 관악구에 위치해 있었는데 금천구로 이전했기 때문에 변경해줘야 한다.
라고 되어있는데 이 데이터는 이미 금천구로 바뀌어 있어서 작업이 필요가 없다. ㅜ

In [12]:
# 금천서를 찾아준다.
crime_anal_police[crime_anal_police['관서명']=='금천서']
Out[12]:
관서명 살인 발생 살인 검거 강도 발생 강도 검거 강간 발생 강간 검거 절도 발생 절도 검거 폭력 발생 폭력 검거 구별
15 금천서 3 4 6 6 151 122 1567 888 2054 1776 금천구
In [13]:
# 매번 데이터를 만드는 작업을 처음부터 할 수 없기때문에 저장을 하자.
crime_anal_police.to_csv('pydata/02. crime_in_Seoul_include_gu_name.csv', sep=',', encoding='utf-8')
In [14]:
crime_anal_police.head()
Out[14]:
관서명 살인 발생 살인 검거 강도 발생 강도 검거 강간 발생 강간 검거 절도 발생 절도 검거 폭력 발생 폭력 검거 구별
0 중부서 2 2 3 2 105 65 1395 477 1355 1170 중구
1 종로서 3 3 6 5 115 98 1070 413 1278 1070 종로구
2 남대문서 1 0 6 4 65 46 1153 382 869 794 중구
3 서대문서 2 2 5 4 154 124 1812 738 2056 1711 서대문구
4 혜화서 3 2 5 4 96 63 1114 424 1015 861 종로구

같은 구에 2개 이상의 경찰서가 있을수 있기 때문에 구별에는 같은 구가 2번 이상 있을 수 있다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
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
글 보관함