# 선요약
1. googlemaps로 구글맵API를 이용할 수 있다.
2. pivot_table를 사용해서 중복된 인덱스나 칼럼을 병합해서 재구조화 할 수 있다.
3. 데이터의 scale를 통일하기 위해서는 정규화(normalization)가 필요한데, preprocessing의 MinMaxScaler와 fit_transform를 사용하여 정규화를 할 수 있다.
4. seaborn은 heatmap 등의 더 많은 시각화 기능을 제공한다.
5. folium은 위도와 경도 등의 정보를 받아서 지도 시각화 기능을 제공한다.
구글 api 이용해서 정보 모으고 df 만들기
import numpy as np
import pandas as pd
import googlemaps
#csv파일 읽기
crime_anal_police = pd.read_csv('./data/crime_in_Seoul.csv', thousands=',',encoding='euc-kr')
print(crime_anal_police.head())
#구글맵API 불러오기
gmaps_key = "-"
gmaps = googlemaps.Client(key=gmaps_key)
#경찰서이름 바꿔서 리스트로 저장
station_name = []
for name in crime_anal_police["관서명"]:
station_name.append('서울'+str(name[:-1])+'경찰서')
#경찰서 이름으로 주소 받아오기
station_address=[] #주소 이름
station_lat=[] #위도
station_lng=[] #경도
for name in station_name:
tmp = gmaps.geocode(name, language='ko') #이름으로 geocode 받기
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'])
#구이름 열 추가하기
gu_name=[]
for name in station_address:
tmp=name.split() #주소 문자열 -> 리스트
tmp_gu=[gu for gu in tmp if gu[-1] == '구'][0] #tmp_gu는 만들어진 리스트의 첫번째 요소, 이름 문자열
gu_name.append(tmp_gu)
crime_anal_police['구별']=gu_name #data frame에 구별 열 추가해서 gu_name 리스트 넣기
print(crime_anal_police.head())
#특정열의 특정값을 갖는 행 찾고 -> loc으로 행, 열 위치 받아서 다른 값으로 변경하기
crime_anal_police[crime_anal_police['관서명']=='금천서'] #조건문으로 여러개의 행 가져오려면 괄호 씌우기
crime_anal_police.loc[crime_anal_police['관서명']=='금천서', ['구별']] = '금천구' #df.loc(행, 열) = 'Data'
#data frame를 csv로 저장해두기
crime_anal_police.to_csv('./data/crime_in_Seoul_include_gu_name.csv', sep=',', encoding='utf-8')
with open('./data/station_lat.txt', 'w') as f:
for item in station_lat:
f.write("%s\n" % item)
with open('./data/station_lng.txt', 'w') as f:
for item in station_lng:
f.write("%s\n" % item)
f.close()
df 변경하기
import numpy as np
import pandas as pd
import googlemaps
#csv파일 읽기
crime_anal_police = pd.read_csv('./data/crime_in_Seoul_include_gu_name.csv',encoding='utf-8',index_col=0)
#pivot table로 구별 인덱스로 중복 없애서 정렬하기
crime_anal = pd.pivot_table(crime_anal_police, index='구별', aggfunc=np.sum)
#del columns
crime_anal['강간검거율']=crime_anal['강간 검거']/crime_anal['강간 발생']*100
crime_anal['강도검거율']=crime_anal['강도 검거']/crime_anal['강도 발생']*100
crime_anal['살인검거율']=crime_anal['살인 검거']/crime_anal['살인 발생']*100
crime_anal['절도검거율']=crime_anal['절도 검거']/crime_anal['절도 발생']*100
crime_anal['폭력검거율']=crime_anal['폭력 검거']/crime_anal['폭력 발생']*100
del crime_anal['강간 검거']
del crime_anal['강도 검거']
del crime_anal['살인 검거']
del crime_anal['절도 검거']
del crime_anal['폭력 검거']
con_list = ['강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율']
for column in con_list:
crime_anal.loc[crime_anal[column]>100, column]=100
crime_anal.rename(columns = {'강간 발생':'강간','강도 발생':'강도','살인 발생':'살인','절도 발생':'절도','폭력 발생':'폭력'}, inplace=True)
print(crime_anal.head())
#normalization
from sklearn import preprocessing
col = ['강간','강도','살인','절도','폭력']
x=crime_anal[col].values
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled=min_max_scaler.fit_transform(x.astype(float))
crime_anal_norm=pd.DataFrame(x_scaled, columns=col, index=crime_anal.index)
crime_anal_norm[con_list]=crime_anal[con_list]
#add columns
result_CCTV = pd.read_csv('./data/cctv_result.csv', encoding='UTF-8', index_col='구별')
crime_anal_norm[['인구수', 'CCTV']] = result_CCTV[['인구수', '소계']]
crime_anal_norm['범죄'] = np.sum(crime_anal_norm[col], axis=1)
crime_anal_norm['검거'] = np.sum(crime_anal_norm[con_list], axis=1)
#save to csv
crime_anal_norm.to_csv('./data/crime_in_Seoul_normalization.csv', sep=',', encoding='utf-8')
정규화 포함 df 변경
import numpy as np
import pandas as pd
#csv파일 읽기
crime_anal_norm = pd.read_csv('./data/crime_in_Seoul_normalization.csv',encoding='utf-8',index_col=0)
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
import seaborn as sns
#한글처리
plt.rcParams['axes.unicode_minus']=False
rc('font',family='AppleGothic')
#draw plot graph
sns.pairplot(crime_anal_norm, vars=["강도", "살인", "폭력"], kind='reg', height=3)
sns.pairplot(crime_anal_norm, x_vars=["인구수","CCTV"], y_vars=["살인", "강도"], kind="reg", height=3)
#draw heatmap
tmp_max = crime_anal_norm['검거'].max()
crime_anal_norm['검거']=crime_anal_norm['검거']/tmp_max*100
crime_anal_norm['범죄']=crime_anal_norm['범죄']/5 #합의 평균으로 변경
crime_anal_sort=crime_anal_norm.sort_values(by='범죄', ascending=False) #sort
plt.figure(figsize =(10,10))
target_col = ['강간','강도','살인','절도','폭력', '범죄']
cmap = sns.cm.rocket_r
sns.heatmap(crime_anal_sort[target_col], annot=True, fmt='f', linewidths=.5, cmap=cmap)
plt.title('범죄비율 (정규화된 발생 건수로 정렬)')
plt.show()
crime_anal_sort.to_csv('./data/crime_in_Seoul_final.csv', sep=',', encoding='utf-8')
결과 지도에 표시
import numpy as np
import pandas as pd
import folium
import json
#read csv
crime_anal_norm = pd.read_csv('./data/crime_in_Seoul_final.csv',encoding='utf-8',index_col=0)
#인구수 대비 범죄 발생 건수
tmp_criminal=crime_anal_norm['살인']/crime_anal_norm['인구수']*1000000
#add the protect crime rate
crime_anal_raw = pd.read_csv('./data/crime_in_Seoul_include_gu_name.csv',encoding='utf-8',index_col=0)
station_lat = [line.rstrip('\n') for line in open("./data/station_lat.txt")]
station_lng = [line.rstrip('\n') for line in open("./data/station_lng.txt")]
crime_anal_raw['lat'] = station_lat
crime_anal_raw['lng'] = station_lng
col = ['강간 검거','강도 검거','살인 검거','절도 검거','폭력 검거']
tmp = crime_anal_raw[col] / crime_anal_raw[col].max()
crime_anal_raw['검거'] = np.sum(tmp, axis=1)
#new map
map = folium.Map(location=[37.5502, 126.982], zoom_start=11)
#read json and paint
geo_path = './data/seoul_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))
map.choropleth(geo_data=geo_str,
data=crime_anal_norm['범죄'],
columns=[crime_anal_norm.index, crime_anal_norm['범죄']],
fill_color='PuRd',
key_on='feature.id')
#mark station
for n in crime_anal_raw.index:
folium.CircleMarker([crime_anal_raw['lat'][n],
crime_anal_raw['lng'][n]],
radius=crime_anal_raw['검거'][n]*10,
color='#3186cc',
fill_color='#3186cc').add_to(map)
#save map
map.save('./data/map.html')
'데이터 사이언스 공부 > 파이썬으로데이터주무르기' 카테고리의 다른 글
time series (0) | 2020.05.12 |
---|---|
self gas station analysis (0) | 2020.05.12 |
chicago analysis (0) | 2020.05.12 |
cctv analysis (0) | 2020.05.12 |