# -*- coding: utf-8 -*-
"""
Created on Thu Apr 23 09:49:21 2020

@author: admin
"""

'''
서울시 구별 CCTV 현황 분석하기

서울시 각 구별 CCTV 수를 파악하고,
인구대비 CCTV 비율을 파악해서 순위 비교

인구대비 CCTV의 평균치를 확인하고
그로부터 CCTV가 과하게 부족한 구를 확인

Python 기본 문법 / Pandas 와 Matplotlib의 기본적 사용법을 이용한 시각화
단순한 그래프 표현에서
한 단계 더 나아가 경향을 확인하고 시각화하는 기초 확인
 
'''
import pandas as pd
import numpy as np

# CCTV 데이터와 인구 데이터 합치고 분석하기

##CCTV 데이터 읽기
CCTV_Seoul = pd.read_csv('./data/01. CCTV_in_Seoul.csv', encoding='UTF-8')
#데이터프레임
CCTV_Seoul.head()

CCTV_Seoul.columns

CCTV_Seoul.columns[0]

#칼럼명 변경 : 기관명을 구별로 변경 
CCTV_Seoul.rename(columns={CCTV_Seoul.columns[0]:'구별'}, inplace=True)
CCTV_Seoul.head()


# 인구데이터 읽기 1
pop_Seoul = pd.read_excel('./data/01. population_in_Seoul.xls', encoding='UTF-8')
pop_Seoul.head()

#인구 데이터 읽기2 - 필요한 데이터만 선별하여 읽기
pop_Seoul = pd.read_excel('./data/01. population_in_Seoul.xls',
                          header=2, # 헤더 두 줄 건너 뛰고 나타내라
                          usecols='B, D, G, J, N', # 사용할 컬럼 지정
                          encoding='utf-8')

pop_Seoul.head()

#계라고 나오는 컬럼을 알기 쉬운 컬럼명으로 변경
pop_Seoul.rename(columns={pop_Seoul.columns[0]:'구별',
                          pop_Seoul.columns[1]:'인구수',
                          pop_Seoul.columns[2]:'한국인',
                          pop_Seoul.columns[3]:'외국인',
                          pop_Seoul.columns[4]:'고령자'},inplace=True)

pop_Seoul.head()

#CCTV 데이터 파악하기
# 소계 순으로 정렬(오름차순)
CCTV_Seoul.sort_values(by='소계', ascending=True).head(5)
# 소계 순으로 정렬(내차순)
CCTV_Seoul.sort_values(by='소계', ascending=False).head(5)
#sort_values : 원본에 정렬순으로 저장되는 것은 아니다.


# 최근증가율 = (2016년+2015년+2014년)/2013년도 이전 * 100
CCTV_Seoul['최근증가율']=(CCTV_Seoul['2016년']+CCTV_Seoul['2015년']+ \
                     CCTV_Seoul['2014년']) / CCTV_Seoul['2013년도 이전'] * 100
    
    
CCTV_Seoul.sort_values(by='최근증가율', ascending=False).head()


#서울시 인구데이터 파악하기
pop_Seoul.head()

#첫번째 합계 행 삭제
pop_Seoul.drop([0],inplace=True)
pop_Seoul,head()

#'구별' 칼럼의 중복값 제거
pop_Seoul['구별'].unique()

#'구별' 칼럼의 NULL 값 확인
#isnull() : 널값의 행값과 널값을 인덱스 번호를 반환 시켜준다.
#     구별  인구수  한국인  외국인  고령자
#26  NaN  NaN  NaN  NaN  NaN
pop_Seoul[pop_Seoul['구별'].isnull()]

# '구별' 컬럼의 NULL값 있는 행 제거
pop_Seoul.drop([26],inplace=True)
pop_Seoul.head()

'''
데이터 분석
1.분석데이터 수집(R or python )
2.수집된 데이터 형식 확인 및 로컬 전처리
3.분석 prg에서 수집 데이터 읽기
4.읽은 데이터 확인 및 3차 전처리
'''

#외국인비율과 고령자 비율 추가
pop_Seoul['외국인비율']=pop_Seoul['외국인']/pop_Seoul['인구수']*100
pop_Seoul['고령자비율']=pop_Seoul['고령자']/pop_Seoul['인구수']*100
pop_Seoul.head()

# 각 칼럼 확인
pop_Seoul.sort_values(by='인구수', ascending=False).head()
pop_Seoul.sort_values(by='외국인', ascending=False).head()
pop_Seoul.sort_values(by='외국인비율', ascending=False).head()
pop_Seoul.sort_values(by='고령자', ascending=False).head()
pop_Seoul.sort_values(by='고령자비율', ascending=False).head()

# 시각화 작업을 위함 구이름('구별')을 index화
data_result.set_index('구별', inplace=True)
data_result.head()


###CCTV 데이터와 인구 데이터 합치고 분석하기

# 두개의 데이터프레임을 합할 경우 동일 컬럼명은 하나('구별')로 통일 된다.
data_result = pd.merge(CCTV_Seoul,pop_Seoul, on='구별') 
data_result.head() 

# CCTV에 대한 '소계' 컬럼을 제외한 나머지 CCTV 데이터 삭제
del data_result['2013년도 이전']
del data_result['2014년']
del data_result['2015년']
del data_result['2016년']
data_result.head()

#CCTV와 각 칼럼에 대한 상솬관계 분석
# 상관관계 함수 :np.corrcoef()
np.corrcoef(data_result['고령자비율'],data_result['소계'])
np.corrcoef(data_result['외국인비율'],data_result['소계'])
np.corrcoef(data_result['인구수'],data_result['소계'])
data_result.sort_values(by='소계', ascending=False).head(5)

#csv로 저장시켜주는 함수
data_result.to_csv('data_result.csv')
# 데이터 읽히는지 확인하기
pd.read_csv('data_result.csv', encoding='utf-8')

 

# CCTV와 인구현황 그래프로 분석하기

import platform
import pandas as pd
import numpy as np

# 폰트 설정(특히 한글부분)
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
plt.rcParams['axes.unicode_minus']=False

data_result = pd.read_csv('data_result.csv', encoding='utf-8')

if platform.system() == 'Darwin':
    rc('font', family='AppleGothic')
elif platform.system() == 'Windows':
    path = "c:/Windows/Fonts/malgun.ttf"
    font_name = font_manager.FontProperties(fname=path).get_name()
    rc('font', family=font_name)
else:
    print('Unknown system.... sorry')
    
# CCTV 비율을 구하고 그에 따른 시각화 작업
data_result['CCTV비율'] = data_result['소계'] / data_result['인구수'] * 100

data_result['CCTV비율'].sort_values().plot(kind='barh', grid=True, figsize=(10,10))
plt.show()

# 산점도(인구수와 소계)
plt.figure(figsize=(6,6))
plt.scatter(data_result['인구수'], data_result['소계'], s=50)
plt.xlabel('인구수')
plt.ylabel('CCTV')
plt.grid()
plt.show()

# 인구수와 CCTV는 상관계수가 양의 값이므로 산점도와 직선
# 직선 구하기 (Polyfit을 이용한 회귀선)
# polyfit 함수를 이용해서 예측 모델 z의 계수를 생성
fp1 = np.polyfit(data_result['인구수'], data_result['소계'],1)
fp1

# 만들어진 예측 모델을 이용한 그래프 그리기
f1 = np.poly1d(fp1) # y축 데이터
fx = np.linspace(100000, 700000, 100) # x축 데이터

plt.figure(figsize = (10, 10))
plt.scatter(data_result['인구수'], data_result['소계'], s=50)
plt.plot(fx, f1(fx), ls='dashed', lw=3, color = 'g')
plt.xlabel('인구수')
plt.ylabel('CCTV')
plt.grid()
plt.show()
'''인구수가 310000 정도일 때, cctv는 1100대가 적당하다'''

# 조금더 설득력 있는 자료 만들기
'''
직선이 전체 데이터의 대표값 역할을 한다면 
인구수가 300,000일경우 CCTV는 1100정도여야 한다는 결론
가독성 향상을 위해 오차를 계산할 수 있는 코드 작성후,
오차가 큰 순으로 데이터를 정렬
'''
fp1 = np.polyfit(data_result['인구수'], data_result['소계'],1)

f1 = np.poly1d(fp1) # y축 데이터
fx = np.linspace(100000, 700000, 100) # x축 데이터

data_result['오차'] = np.abs(data_result['소계']- f1(data_result['인구수']))
df_sort = data_result.sort_values(by = '오차', ascending =False)
df_sort.head()

#plot 크기 설정
plt.figure(figsize=(14,10))

#산점도
plt.scatter(data_result['인구수'],data_result['소계'],
            c =data_result['오차'], s=50)

#회귀선
plt.plot(fx,f1(fx),ls='dashed', lw=3, color='g')

#주요 10개 지역 구이름 출력
for n in range(10):
    plt.text(df_sort['인구수'][n]*1.02, df_sort['소계'][n]*0.98,
             df_sort.index[n], fontsize=15)

plt.xlabel('인구수')
plt.ylabel('인구당비율')
plt.colorbar() #오른쪽에 생상바
plt.grid() #가이드라인
plt.show()

 

# =============================================================================
#  강남 3구는 안전한가 ?
# =============================================================================

'''
강남 3구의 주민들이 자신들이 거주하는 구의 체감 안전도를
높게 생각한다는 기사를 확인해보도록 한다.
기사 원문 : 

Matplotlib 의 heatmap 등을 그릴 때
cmap의 디폴트 설정이 변경되어 heatmap 등에서 cmap을 적용할 때
옵션을 잡아주어야 동일한 효과가 나타난다.

Folium 0.4.0으로 버전업 되면서
choropleth 명령에서 geo_str 옵션명이 geo_data 옵션명으로 변경됨.
circle marker 적용할 때, fill=True 옵션을 반드시 사용해야 함.
'''

##########
# 데이터 정리하기
# 필요한 모듈을 import

import numpy as np
import pandas as pd

'''다운받은 데이터(csv) 파일을 읽는다,
콤마(,)로 천단위가 구분되어 있고, 한글 인코딩은 euc-kr
'''

crime_anal_police = pd.read_csv('./data/02. crime_in_Seoul.csv',
                                thousands = ',', encoding='euc-kr')

r=crime_anal_police.head()
print(r)

'''
관서별로 되어 있는 데이터를 소속 구별로 변경
1. 경찰서 이름으로 구 정보 얻기
'''
# 구글 맵스를 사용해서 경찰서의 위치(위도, 경도) 정보를 받아온다.
import  googlemaps

# 자신의 key를 사용.
gmaps_key = "AIzaSyC8BVOCtGMXacY8URBfmH1SWiYIErRWJ5M"
gmaps = googlemaps.Client(key=gmaps_key)
r=gmaps.geocode('서울중부경찰서', language='ko')
print(r)

#중부서, 수서서 => 서울**경찰서로 변경
station_name=[]
for name in crime_anal_police['관서명']:
    station_name.append('서울'+ str(name[:-1])+'경찰서')
    
print(station_name)

# 경찰서 이름을 이용하여 주소 얻기
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"))

print(station_address)

station_address

for name in station_name:
    tmp=gmaps.geocode(name,language='ko')
    '''
    [{'address_components': 
        [{'long_name': '617', 
        'short_name': '617', 
        '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': '135-240', 'short_name': '135-240', 
        'types': ['postal_code']}], 
    'formatted_address': '대한민국 서울특별시 강남구 개포동 개포로 617', 
    'geometry': 
        {'location': {'lat': 37.49349, 'lng': 127.0772119}, 'location_type': 'ROOFTOP', 
            'viewport': 
                {'northeast': {'lat': 37.4948389802915, 'lng': 127.0785608802915}, 
            'southwest': {'lat': 37.49214101970851, 'lng': 127.0758629197085}}}, 
    'place_id': 'ChIJY2ee_TGkfDURAWUtC8jBHag', 
    'plus_code': 
        {'compound_code': 'F3VG+9V 대한민국 서울특별시', 
         'global_code': '8Q99F3VG+9V'}, 
    'types': ['establishment', 'point_of_interest', 'police']
    }]
    '''
    station_address.append(tmp[0].get("formatted_address"))
    #formatted_address': '대한민국 서울특별시 강남구 개포동 개포로 617'
    
    

    tmp_loc=tmp[0].get("geometry")
    #{'location': {'lat': 37.49349, 'lng': 127.0772119}
    
    
    #print(tmp_loc)
    '''
    {'location': {'lat': 37.49349, 'lng': 127.0772119}, 
    'location_type': 'ROOFTOP', 
    'viewport': {'northeast': {'lat': 37.4948389802915, 'lng': 127.0785608802915}, 
    'southwest': {'lat': 37.49214101970851, 'lng': 127.0758629197085}}}
    '''
    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 ....
    '''
print(station_address)
print(station_lng)


'''
금천 경찰서의 경우 관악구로 되어 있어서 금천구로 변경
'''
crime_anal_police[crime_anal_police['관서명']=='금천서']
crime_anal_police.loc[crime_anal_police['관서명']==금천서,
                      ['구별']] =='금천구'

crime_anal_police[crime_anal_police['관서명']=='금천서']

#현재까지 작업 내용 저장.
crime_anal_police.to_csv('./dada/02_crime_in_Seoul_include_gu_name.csv',
                         sep = ',', encoding='utf-8')

####### 범죄데이터 구별로 정리하기
from GangnamSatety_20200423 import station_lng, station_lat
crime_anal_raw = pd.read_csv('./data/02_crime_in_Seoul_include_gu_name.csv', encoding='utf-8')

crime_anal_raw.head()
### pandas의 pivot_table

'''
pd.pivot_table(df,                피벗 테이블을 만들기 위한 기본 데이터
               index = [],        pivot_table의 index를 설정(multi index도 가능)
               columns = [],      원하는 columns을 설정
               values = [],       columns에 해당하는 값
               aggfunc = [],      분석을 위한 파라미터
                                  예) np.sum, np.mean 사용
               fill_value = 0,    Nan 값을 채우기.
               margins = True)    모든 데이터의 결과를 아래에 붙일 것인지 설정

--> 원하는 컬럼을 인덱스화 시켜서 나머지 데이터들을 재정렬시켜주는 것이 피벗 테이블의 역할이다.
'''

# pivot_table을 이용
# 저장한 데이터를 관서별에서 구별로..
crime_anal = pd.pivot_table(crime_anal_raw, index='구별', aggfunc=np.sum)
crime_anal.head()

print(crime_anal)
print(type(crime_anal))
'''
각 범죄별 검거율을 계산하고,
검거 건수는 검거율로 대체한 후, 검거 건수는 삭제
'''

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['폭력 검거']

print(crime_anal.head())


'''
100이 넘는 숫자들은 100으로 처리
'''

con_list = ['강간검거율', '강도검거율', '살인검거율', '절도검거율', '폭력검거율']

for columns in con_list:
    crime_anal.loc[crime_anal[column]>100, column] =100
    
print(crime_anal.head())

# 컬럼 뒤에 발생이라는 단어 삭제 : rename()을 이용
crime_anal.rename(columns = {'강간 발생':'강간',
                             '강도 발생':'강도',
                             '살인 발생':'살인',
                             '절도 발생':'절도',
                             '폭력 발생':'폭력',}, inplace = True)

print(crime_anal.head())


################
# 데이터 표현을 위해 전처리 
'''
강도와 살인은 두 자리수,
절도와 폭력은 네 자리수로 구성 되어 있어
각각을 비슷한 범위에 놓고 비교하는 것이 편리하기 때문에
각 컬럼별로 정규화(normalize) 작업

각 항목의 최대값을 1로 두면,
추후 범죄발생 건수를 종합적으로 비교할 때 편리

각각, 강도, 살인, 절도, 폭력에 대하여
각 컬럼별로 정규화(normalize)
'''
'''
파이썬의 머신러닝에 관한 모듈 중
scikit learn에 있는 전처리(preprocessing) 도구에는
최소, 최대값을 이용하여 정규화시키는 함수가 존재 : MinMaxScaler()
'''

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)


# 정규화된 데이터프레임에 검거율 추가
col2 = ['강간검거율', '강도검거율', '살인검거율', '절도검거율', '폭력검거율']

crime_anal_norm[col2] = crime_anal[col2]

print(crime_anal_norm.head())

# CCTV_result.csv 에서 구별 인구수와 CCTV 개수만 추가
result_CCTV = pd.read_csv('./data/01. CCTV_result.csv', encoding='UTF-8', index_col = '구별')

crime_anal_norm[['인구수', 'CCTV']] = result_CCTV[['인구수', '소계']]

print("인구수와 CCTV 개수 =>", crime_anal_norm.head())
# 발생 건수의 합을 '범죄'라는 컬럼으로 합하여 추가

col = ['강간', '강도', '살인', '절도', '폭력']

crime_anal_norm['범죄'] = np.sum(crime_anal_norm[col], axis=1)

print("범죄라는 컬럼으로 합 =>", crime_anal_norm.head())
# 검거율도 통합하여 추가

col = ['강간검거율','강도검거율', '살인검거율','절도검거율','폭력검거율']

crime_anal_norm['검거'] = np.sum(crime_anal_norm[col], axis=1)

print('검거율도 통합 =>', crime_anal_norm.head())

import matplotlib.pyplot as plt

import seaborn as sns # 다수의 상관관계 표현하기 위한 모듈
import platform       # 한글 폰트 설정하기 위한 모듈
import pivotTable_20200423
from pivotTable_20200423 import crime_anal_norm
# 한글 폰트 설정
path = "c:/Windows/Fonts/malgun.ttf"
from matplotlib import font_manager, rc

if platform.system() == 'Darwin':
    rc('font', family='AppleGothic')
elif platform.system() == 'Windows':
    path = "c:/Windows/Fonts/malgun.ttf"
    font_name = font_manager.FontProperties(fname=path).get_name()
    rc('font', family=font_name)
else:
    print('Unknown system.... sorry')
    
# pairplot() 상관관계 : '강도', '살인', '폭력'

#'''
sns.pairplot(crime_anal_norm, vars=["강도", "살인", "폭력"], kind = 'reg', size=3)
plt.show()
#'''

# pairplot() 상관관계 : "인구수", "CCTV", "살인", "강도"
# '''
sns.pairplot(crime_anal_norm, x_vars=["인구수", "CCTV"], y_vars =["살인","강도"], kind='reg', size=3)
plt.show()
# '''


# pairplot() 상관관계 : "인구수", "CCTV", "살인검거율", "폭력검거율"
sns.pairplot(crime_anal_norm, x_vars=["인구수", "CCTV"], y_vars=["살인검거율", "폭력검거율"], kind='reg', size=3)
plt.show()
'''
살인 및 폭력 검거율과 CCTV의 관계가 음의 상관계수도 보여줌.
인구수와 살인 및 폭력 검거율도 음의 상관관계를 보임.
'''
# pairplot() 상관관계 : "인구수", "CCTV", "절도검거율", "강도검거율"
sns.pairplot(crime_anal_norm, x_vars=["인구수", "CCTV"], y_vars=["절도검거율","강도검거율"],kind = 'reg', size=3)
plt.show()
# 검거율의 합계인 검거 항목 최고 값을 100으로 한정한 후, 그 값으로 정렬
tmp_max = crime_anal_norm['검거'].max()
crime_anal_norm['검거'] = crime_anal_norm['검거'] / tmp_max *100
crime_anal_norm_sort = crime_anal_norm.sort_values(by='검거', ascending=False)
crime_anal_norm_sort.head()
# heatmap 으로 시각화
target_col = ['강간검거율','강도검거율','살인검거율','절도검거율','폭력검거율']

crime_anal_norm_sort = crime_anal_norm.sort_values(by = '검거', ascending=False)

plt.figure(figsize=(10,10))

sns.heatmap(crime_anal_norm_sort[target_col],
            annot=True, fmt='f',
            linewidths=.5,     #linewidth는 칸 간격 의미.
            cmap = 'RdPu')

plt.title('범죄 검거 비율 (정규화된 검거의 합으로 정렬)')
plt.show()

# 발생 건수 정렬하여 heatmap으로 시각화
target_col = ['강간', '강도', '살인' ,'절도', '폭력', '범죄']

crime_anal_norm['범죄'] = crime_anal_norm['범죄'] / 5

crime_anal_norm_sort = crime_anal_norm.sort_values(by ='범죄', ascending=False)
plt.figure(figsize=(10,10))
sns.heatmap(crime_anal_norm_sort[target_col],
            annot=True, fmt='f',
            linewidths=.5,
            cmap='RdPu')

plt.title("범죄비율 (정규화 된 발생 건수로 정렬)")
plt.show()

import json

geo_path = './data/02. skorea_municipalities_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))

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)

crime_anal_raw.head()

import folium
import webbrowser


################
# 지도를 이용한 시각화 작업을 위해 지도의 중심 좌표를 이용하여 12배 확대
map = folium.Map(location = [37.5502, 126.982], zoom_start=12)

# 로드된 지도 위에 각 경찰서의 검거율을 x10 배수의 크기(반지름)로 원을 그려준다.(외경 선과 내면 색 지정)
# .add_to()함수로 불러온 map 에 더해줌
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',
                        fill=True).add_to(map)

# map html파일로 저장 후 열기
map
map.save('folium_kr2.html')
webbrowser.open_new("folium_kr2.html")

##############
map = folium.Map(location = [37.5502, 126.982], zoom_start=12)

map.choropleth(geo_data=geo_str,
               data = crime_anal_norm['범죄'],
               columns = [crime_anal_norm.index, crime_anal_norm['범죄']],
               fill_color='PuRd',   #PuRd, YlGnBu
               key_on = 'feature.id')

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',
                        fill=True).add_to(map)

map.save('folium_kr3.html')
webbrowser.open_new("folium_kr3.html")

 

# =============================================================================
# 위에는 TL_SCCO_SIG_WGS84.json, Total_People_2018.csv 데이터로 맵 구역별로 나눈거 하기
# 아래는 외국인 거주자 인구수 데이터
# =============================================================================

import matplotlib.pyplot as plt

import seaborn as sns # 다수의 상관관계 표현하기 위한 모듈
import platform       # 한글 폰트 설정하기 위한 모듈
import pandas as pd
import numpy as np

import json

import folium
import webbrowser


pop_Seoul = pd.read_excel('./data/01. population_in_Seoul.xls', encoding='utf-8')

pop_Seoul.head()

pop_Seoul = pd.read_excel('./data/01. population_in_Seoul.xls',
                          header=2, # 2줄 건너뛰고 읽어온다
                          usecols='B, D, J', # 원하는 셀만 골라서 가져오기
                          encoding='utf-8')

pop_Seoul.head() 

# 알기 쉬운 컬럼명으로 변경
pop_Seoul.rename(columns={pop_Seoul.columns[0]:'구별',
                          pop_Seoul.columns[1]:'인구수',
                          pop_Seoul.columns[2]:'외국인거주인구'}, inplace=True)
pop_Seoul.head()

pop_Seoul.drop([0], inplace=True)
pop_Seoul.head()


# '구별' 컬럼의 중복값제거
pop_Seoul['구별'].unique()

# '구별' 컬럼의 NULL 값 확인
pop_Seoul[pop_Seoul['구별'].isnull()] # NULL 값이 있는 행 번호 & 값들을 함께 반환시켜준다.

# '구별' 컬럼의 NULL값 있는 행 제거
pop_Seoul.drop([26],inplace=True)
pop_Seoul.head()

#비율 추가
pop_Seoul['외국인비율']=pop_Seoul['외국인거주인구']/pop_Seoul['인구수']*100

#각 컬럼 확인
pop_Seoul.sort_values(by='인구수', ascending=False).head()
pop_Seoul.sort_values(by='외국인거주인구', ascending=False).head()

# 시각화 작업을 위한 구 이름('구별')을 index 화
pop_Seoul.set_index('구별', inplace=True)
pop_Seoul


geo_path = './data/02. skorea_municipalities_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))

# # 지도를 이용한 시각화 작업을 위해 지도의 중심 좌표를 이용하여 12배 확대
map = folium.Map(location = [37.5502, 126.982], zoom_start=12)

map.choropleth(geo_data=geo_str,
               data = pop_Seoul['외국인비율'],
               columns = [pop_Seoul.index, pop_Seoul['외국인비율']],
               fill_color='PuRd',
               key_on = 'feature.id')

map.save('folium_foreingn.html')
webbrowser.open_new("folium_foreingn.html")

+ Recent posts