- googlemaps, folium, seaborn, pandas-pivot_table 활용
- import moduel, 데이터 정리
import numpy as np
import pandas as pd
# 1000을 1,000으로 배포된 데이터 숫자로 읽기(문자로 인식하기 때문에)
crime_raw_data=pd.read_csv('../data/02.crime_in_seoul.csv',thousands=',',encoding='euc-kr'
# null이 아닌 값만 사용
crime_raw_data[crime_raw_data['죄종'].notnull()]
# 경찰서 이름을 index, default값이 평균이기 때문에 사건의 합으로 변경
crime_station=pd.pivot_table(crime_raw_data,index=['구분'],columns=['죄종','발생검거'],aggfunc=[np.sum])
crime_station.head()
# 다중 컬럼에서 특정 컬럼 제거
crime_station.columns=crime_station.columns.droplevel([0,1])
- googlemaps
import googlemaps
gmaps_key='AIzaSyBAIYeQFSLUYyDX2vQY3TRatW72qtFRduQ'
gmaps=googlemaps.Client(key=gmaps_key)
# 경찰서 이름을 구이름으로 변경하기
gmaps.geocode('서울영등포경찰서',language='ko')
# 경찰서 이름에서 소속된 구이름 얻기
# 구 이름과 위도 경도 정보 저장 준비
# 반복문 이용 => nan값 채우기
crime_station['구별']=np.nan
crime_station['lat']=np.nan
crime_station['lng']=np.nan
# 구 이름 가져오기
count=0
for idx, rows in crime_station.iterrows():
# print(idx)
station_name='서울 ' + str(idx) + ' 경찰서'
print(station_name)
tmp=gmaps.geocode(station_name,language='ko')
tmp[0].get('formatted_address')
tmp_gu = tmp[0].get('formatted_address')
lat=tmp[0].get('geometry')['location']['lat']
lng=tmp[0].get('geometry')['location']['lng']
crime_station.loc[idx,'lat']=lat
crime_station.loc[idx,'lng']=lng
crime_station.loc[idx,'구별']=tmp_gu.split()[2]
print(count)
count=count+1
# 컬럼 이름 합치기 강간 + 검거
tmp=[
crime_station.columns.get_level_values(0)[n] + crime_station.columns.get_level_values(1)[n]
for n in range(0,len(crime_station.columns.get_level_values(0)))
]
crime_station.columns = tmp
- 구별 데이터로 정리
# '구분'을 인덱스 컬럼으로 설정 index_col=0
crime_anal_station=pd.read_csv('../data/02. crime_in_Seoul_raw.csv',index_col=0,encoding='utf-8')
crime_anal_station.head()
#피벗테이블로 만들기
crime_anal_gu=pd.pivot_table(crime_anal_station,index='구별',aggfunc=np.sum)
del crime_anal_gu['lat']
crime_anal_gu.drop('lng',axis=1,inplace=True)
#검거율 생성
target=['강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율']
num=['강간검거','강도검거','살인검거','절도검거','폭력검거']
den=['강간발생','강도발생','살인발생','절도발생','폭력발생']
crime_anal_gu[target] = crime_anal_gu[num].div(crime_anal_gu[den].values) *100
# 필요 없는 컬럼 제거
crime_anal_gu.drop(['절도검거','폭력검거'],axis=1,inplace=True)
# 100보다 큰 숫자 찾아서 바꾸기
crime_anal_gu[crime_anal_gu[target].head() > 100] =100
crime_anal_gu.head()
# 컬럼 이름 변경
crime_anal_gu.rename(columns={'강간발생':'강간','살인발생':'살인','강도발생':'강도','절도발생':'절도','폭력발생':'폭력'}
,inplace=True)
- 범죄 데이터 정리
# 정규화 : 최고값 1. 최소값 0
crime_anal_gu['강도']/crime_anal_gu['강도'].max()
col=['살인','강도','절도','폭력','강간']
crime_anal_norm=crime_anal_gu[col]/crime_anal_gu[col].max()
# 검거율 추가
col2=['살인검거율','강도검거율','강간검거율','절도검거율','폭력검거율']
crime_anal_norm[col2]=crime_anal_gu[col2]
# 구별 cctv 자료에서 인구수와 cctv수 추가
result_cctv=pd.read_csv('../data/01. CCTV_result.csv',index_col='구별',encoding='utf-8')
crime_anal_norm[['인구수','CCTV']]=result_cctv[['인구수','소계']]
# 정규화된 범죄발생 건수 전체의 평균을 구해서 범죄 대표값으로 사용
col = ['강간','강도','절도','폭력','살인']
crime_anal_norm['범죄']=np.mean(crime_anal_norm[col],axis=1)
- seaborn(상관관계 알아보기)
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib as rc
plt.rcParams['axes.unicode_minus']=False
get_ipython().run_line_magic('matplotlib','inline')
plt.rc('font',family='Malgun Gothic')
# pairplot 강도, 살인, 폭력에 대한 상관관계 확인
sns.pairplot(data=crime_anal_norm,vars=['살인','강도','폭력'],kind='reg',height=3)
- folium.Choropleth(지도 시각화)
import json
my_map=folium.Map(
location=[37.5502,126.982],zoom_start=14,tiles='Stamen Toner')
# 5대 범죄 발생 건수 지도 시가과
folium.Choropleth(
geo_data=geo_str, data=crime_anal_norm['범죄'],
columns=[crime_anal_norm.index,crime_anal_norm['범죄']],
key_on='feature.id', fill_color='PuRd',
fill_opacity=0.7, line_opacity=0.2,
legend_name='정규화된 5대 범죄 발생 건수'
).add_to(my_map)
my_map