본문 바로가기
PYTHON

20200423 - 파이썬, CCTV, 인구수, 서울시 범죄율 분석, 시각화, 피벗테이블

by 낫싱 2020. 4. 23.
728x90
반응형

20200423_Matplotlib_FONT.py
0.00MB
20200423-DataScience.py
0.01MB
data_result.csv
0.00MB
folium_foreingn.html
0.04MB
Foreign_pop_map_20200423.py
0.00MB
GangnamSafety_20200423.py
0.00MB
korTOTAL_pop_map_20200423.py
0.00MB
Pairplot_20200423.py
0.01MB
pivotTable_20200423.py
0.01MB
POP_totalKOR.html
1.45MB

 

 

대표사진 삭제

사진 설명을 입력하세요.

대표사진 삭제

사진 설명을 입력하세요.

 

전송중...

사진 설명을 입력하세요.

 

전송중...

사진 설명을 입력하세요.

''' 서울시 구별 CCTV 현황 분석하기 서울시 각 구별 CCTV 수를 파악하고, 인구대비 CCTV 비율을 파악해서 순위 비교 인구대비 CCTV의 평균치를 확인하고 그로부터 CCTV가 과하게 부족한 구를 확인 Python 기본 문법 / Pandas 와 Matplotlib의 기본적 사용법을 이용한 시각화 단순한 그래프 표현에서 한 단계 더 나아가 경향을 확인하고 시각화하는 기초 확인 ''' import pandas as pd import numpy as np # CCTV 데이터와 인구 데이터 합치고 분석하기 CCTV_Seoul = pd.read_csv('./data/01. CCTV_in_Seoul.csv', encoding='utf-8') print(type(CCTV_Seoul)) # <class 'pandas.core.frame.DataFrame'> CCTV_Seoul.head() CCTV_Seoul.columns # dtype='object' : dtype 은 실제 데이터의 타입 print(type(CCTV_Seoul.columns)) # <class 'pandas.core.indexes.base.Index'> '''.columns 가 반환하는 타입은 원래 LIST 타입이다.''' '''시리즈는 index 구역과 value 구역으로 나뉘어 있다.''' CCTV_Seoul.columns[0] # 여기서 시리즈의 인덱스번호로 찾아준 것임. CCTV_Seoul.columns 의 데이터 타입이 object 인 이유 print(type(CCTV_Seoul.columns[0])) # <class 'str'> # 컬럼명 변경 : 기관명을 구별로 변경 CCTV_Seoul.rename(columns={CCTV_Seoul.columns[0] : '구별'}, inplace=True) # 0번의 컬럼명을 구별로 변경, 그 결과값을 다시 CCTV_Seoul.columns[0]에 반영 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, # 2줄 건너뛰고 읽어온다 usecols='B, D, G, J, N', # 원하는 셀만 골라서 가져오기 encoding='utf-8') pop_Seoul.head() # 컬럼명이 동일하기 때문에 .1, .2 가 붙어서 출력된다. # 알기 쉬운 컬럼명으로 변경 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() CCTV_Seoul.sort_values(by='소계', ascending=False).head() # 최근증가율 = (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 값 확인 pop_Seoul[pop_Seoul['구별'].isnull()] # NULL 값이 있는 행 번호 & 값들을 함께 반환시켜준다. # '구별' 컬럼의 NULL값 있는 행 제거 pop_Seoul.drop([26],inplace=True) pop_Seoul.head() ''' 데이터분석 1. 분석 데이터 수집 - 수집하는 방법 1) 어느 사이트의 데이터를 이용하는 방법 2) 기사 & 문서를 이용하는 방법 3) SNS를 이용하는 방법 - API를 이용하면 가능하다. --> data 폴더 생성 2. 수집된 데이터 형식 확인 및 local 전처리 - 프로그램에서 검사하는게 아닌 PC에서 검사해야 한다.(1차 전처리) (excel or csv 파일등은 일단 열어보고 다 필요한지 어디에 있는지, 한글이 깨졌는지를 모두 확인해야 한다.) --> 1차 전처리 된 폴더 생성 3. 분석 prg에서 수집 데이터 읽기 - R로 할 것인지, Python 으로 할 것인지 --> 1차에서 하기 힘든것들은 프로그램을 통해서 전처리 진행 4. 읽은 데이터 확인 및 2차 전처리 ''' # 외국인 비율과 고령자 비율 추가 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() #### CCTV 데이터와 인구 데이터 합치고 분석하기 # 두 개의 데이터프레임을 합할 경우 동일 컬럼명은 하나('구별')로 통일된다. data_result = pd.merge(CCTV_Seoul, pop_Seoul, on='구별') data_result.head() type(data_result) # pandas.core.frame.DataFrame # CCTV에 대한 '소계' 컬럼을 제외한 나머지 CCTV 데이터 삭제 del data_result['2013년도 이전'] del data_result['2014년'] del data_result['2015년'] del data_result['2016년'] data_result.head() # 시각화 작업을 위한 구 이름('구별')을 index 화 data_result.set_index('구별', inplace=True) data_result.head() # CCTV와 각 컬럼에 대한 상관관계 분석 # 상관관계 함수 : np.corrcoef() np.corrcoef(data_result['고령자비율'], data_result['소계']) '''array([[ 1. , -0.28078554], [-0.28078554, 1. ]])''' np.corrcoef(data_result['외국인비율'], data_result['소계']) '''array([[ 1. , -0.13607433], [-0.13607433, 1. ]])''' np.corrcoef(data_result['인구수'], data_result['소계']) '''array([[1. , 0.30634228], [0.30634228, 1. ]])''' data_result.sort_values(by='소계', ascending=False).head(5) # 데이터 저장 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의 계수를 생성 # z계수 : 기존 데이터들을 산점도로 시각화작업 한 경우 회귀선을 그려주는데 그려줄 때 필요한 # 세타(기울어진 각도) 가 필요한데 그 세타값이 z 계수임 # 기울기를 조절하고 싶다면 z계수를 다시 뽑아야 한다. fp1 = np.polyfit(data_result['인구수'], data_result['소계'],1) fp1 # array([1.30916415e-03, 6.45066497e+02]) print(type(fp1)) # <class 'numpy.ndarray'> # 만들어진 예측 모델을 이용한 그래프 그리기 f1 = np.poly1d(fp1) # y축 데이터 print(type(f1)) # <class 'numpy.poly1d'> fx = np.linspace(100000, 700000, 100) # x축 데이터 print(type(fx)) # <class 'numpy.ndarray'> 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) fx = np.linspace(100000, 700000, 100) 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('인구수') # x축 라벨 plt.ylabel('인구당비율') # y축 라벨 plt.colorbar() # 오른쪽에 색상 바 plt.grid() # 가이드 라인 plt.show() # 출력 '''데이터를 분석한다는 의미는 분석에 대한 결과가 있어야 하고, 이에 대한 결론이 나와야 한다.'''

 

 

전송중...

사진 설명을 입력하세요.

 

전송중...

사진 설명을 입력하세요.

 

전송중...

사진 설명을 입력하세요.

# ============================================================================= # 강남 3구는 안전한가 ? # ============================================================================= ''' 강남 3구의 주민들이 자신들이 거주하는 구의 체감 안전도를 높게 생각한다는 기사를 확인해보도록 한다. 기사 원문 : http://news1.kr/articles/?1911504 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 = "AIzaSyDaqk0cpRrmBkT6-77TZLq2LUuml_mnro0" 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) print(type(station_name)) #<class 'list'> # 경찰서 이름을 이용하여 주소 얻기 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")) # 구글에서 보내준 데이터 안에 있는 key 명들임(JSON 형태) tmp_loc = tmp[0].get("geometry") # geometry도 구글에서 보내준 데이터의 key (JSON 형태) station_lat.append(tmp_loc['location']['lat']) # (JSON 형태 key 명) station_lng.append(tmp_loc['location']['lng']) # (JSON 형태 key 명) print(name+'-->' + tmp[0].get("formatted_address")) print(station_address) print(type(station_address)) # <class 'list'> '''저장한 주소를 띄어쓰기, 공백으로 나누고, 구별이라는 컬럼으로 저장.''' 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) ''' tmp_gu = for gu in tmp: if gu[-1] =='구'[0]: name = '대한민국 서울특별시 중구 을지로동 수표로 27', ~~~ tmp = name.split() tmp : '대한민국', '서울특별시', '중구', '을지로동', '수표로', '27' gu : '대한민국' '서울특별시' '중구' ~ '27' ''' crime_anal_police['구별'] = gu_name print(crime_anal_police.head()) ''' 금천 경찰서의 경우 관악구로 되어 있어서 금천구로 변경 ''' crime_anal_police[crime_anal_police['관서명']=='금천서'] crime_anal_police.loc[crime_anal_police['관서명']=='금천서',['구별']] =='금천구' crime_anal_police[crime_anal_police['관서명']=='금천서'] #현재까지 작업 내용 저장. crime_anal_police.to_csv('./data/02_crime_in_Seoul_include_gu_name.csv', sep = ',', encoding='utf-8') # 읽기 내용 확인 pd.read_csv('./data/02_crime_in_Seoul_include_gu_name.csv', encoding='utf-8')

 

 

 

전송중...

사진 설명을 입력하세요.

 

전송중...

사진 설명을 입력하세요.

 

전송중...

사진 설명을 입력하세요.

####### 범죄데이터 구별로 정리하기 import pandas as pd import numpy as np from GangnamSafety_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) 모든 데이터의 결과를 아래에 붙일 것인지 설정 --> 원하는 컬럼을 인덱스화 시켜서 나머지 데이터들을 재정렬시켜주는 것이 피벗 테이블의 역할이다. : 데이터의 열 중에서 두 개의 열을 각각 행 인덱스, 열 인덱스로 사용하여 데이터를 조회하여 펼쳐놓은 테이블 형태 (주의)피벗테이블의 pd.pivot_table은 판다스의 함수이고 dataframe의 set index는 다른 종류이다. ''' # pivot_table을 이용 # 저장한 데이터를 관서별에서 구별로.. crime_anal = pd.pivot_table(crime_anal_raw, index='구별', aggfunc=np.sum) crime_anal.head() print(crime_anal) print(type(crime_anal)) # <class 'pandas.core.frame.DataFrame'> ''' 각 범죄별 검거율을 계산하고, 검거 건수는 검거율로 대체한 후, 검거 건수는 삭제 ''' 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 column 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 print(type(x)) # <class 'numpy.ndarray'> min_max_scaler = preprocessing.MinMaxScaler() print(type(min_max_scaler)) # <class 'sklearn.preprocessing._data.MinMaxScaler'> x_scaled = min_max_scaler.fit_transform(x.astype(float)) print(type(x_scaled)) # <class 'numpy.ndarray'> crime_anal_norm = pd.DataFrame(x_scaled, columns = col, index = crime_anal.index) print(type(crime_anal_norm)) # <class 'pandas.core.frame.DataFrame'> # 정규화된 데이터프레임에 검거율 추가 col2 = ['강간검거율', '강도검거율', '살인검거율', '절도검거율', '폭력검거율'] crime_anal_norm[col2] = crime_anal[col2] print(crime_anal_norm.head()) # ============================================================================= # 사건, cctv, 인구 # 세 가지의 상관관계를 분석한다. # ============================================================================= # 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 pandas as pd import numpy as np from pivotTable_20200423 import crime_anal_norm, crime_anal_raw from GangnamSafety_20200423 import station_lng, station_lat # 한글 폰트 설정 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() # ''' ''' 전체적인 상관계수는 CCTV와 살인의 관계가 낮을지 몰라도 CCTV가 없을 때 살인사건 많은 구간 있음., CCTV수를 기준으로 좌측면에 살인과 강도의 높은 수를 갖는 데이터가 보임. ''' # pairplot() 상관관계 : "인구수", "CCTV", "살인검거율", "폭력검거율" sns.pairplot(crime_anal_norm, x_vars=["인구수", "CCTV"], y_vars=["살인검거율", "폭력검거율"], kind='reg', size=3) # kind='reg'를 작성해야 관계선이 그려진다 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() # 작업물 저장 crime_anal_norm.to_csv('./data/02_crime_in_Seoul_final.csv', sep=',', encoding='utf-8') # 인코딩의 표준이 utf-8이기 때문에 이렇게 저장 # 읽기 내용 확인 pd.read_csv('./data/02_crime_in_Seoul_final.csv', encoding='utf-8') 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) # 로드된 지도 위에 각 경찰서 위치를 marking for n in crime_anal_raw.index: folium.Marker([crime_anal_raw['lat'][n], crime_anal_raw['lng'][n]]).add_to(map) map map.save('folium_kr.html') webbrowser.open_new("folium_kr.html") ################ # 지도를 이용한 시각화 작업을 위해 지도의 중심 좌표를 이용하여 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")

 

 

전송중...

사진 설명을 입력하세요.

 

전송중...

사진 설명을 입력하세요.

# ============================================================================= # 외국인 거주자 인구수 데이터 # ============================================================================= 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")

 

 

전송중...

사진 설명을 입력하세요.

# ============================================================================= # TL_SCCO_SIG_WGS84.json, Total_People_2018.csv 데이터로 맵 구역별로 나누기 - 전국 # ============================================================================= import pandas as pd import numpy as np pop_korea = pd.read_csv("./data/Total_People_2018.csv", encoding='utf-8') pop_korea.head() pop_korea.rename(columns={pop_korea.columns[0]:'코드', pop_korea.columns[1]:'인구수'}, inplace=True) pop_korea.head() import json geo_path = './data/TL_SCCO_SIG_WGS84.json' geo_str = json.load(open(geo_path)) print(geo_str) import folium import webbrowser map = folium.Map(location = [37.5502, 126.982], zoom_start=7) map.choropleth(geo_data=geo_path, data=pop_korea, columns = ['코드', '인구수'], fill_color='YlGn', fill_opacity=0.7, line_opacity=0.5, key_on='feature.properties.SIG_CD') map.save('POP_totalKOR.html') webbrowser.open_new("POP_totalKOR.html")

 

 

 

 

728x90
반응형

댓글