데이터분석/실습
서울시 CCTV 현황 분석
2^7
2022. 5. 31. 19:29
이용 데이터 :https://opengov.seoul.go.kr/data/2813904
목록 > 공공데이터 > 통계정보 > 정보소통광장
목록
opengov.seoul.go.kr
0. 한글 폰트 설치 및 Excel 패키지 업데이트
import matplotlib.font_manager as fm
# Linux
!apt-get -qq -y install fonts-nanum > /dev/null
# Colab
fontpath = '/usr/share/fonts/truetype/nanum/NanumBarunGothic.ttf'
font = fm.FontProperties(fname = fontpath, size = 10)
fm._rebuild()
import matplotlib.pyplot as plt
import matplotlib as mpl
import matplotlib.font_manager as fm
mpl.rcParams['axes.unicode_minus'] = False
path = '/usr/share/fonts/truetype/nanum/NanumGothicBold.ttf' #한글 폰트 설정
font_name = fm.FontProperties(fname = path, size = 10).get_name()
plt.rc('font', family = font_name)
fm._rebuild()
import os
os.kill(os.getpid(), 9) #런타임 강제 종료 후 다시시작
!pip install --upgrade xlrd #excel 패키지 업데이트
1.'seoulCCTV.csv' 파일 전처리
1-1. 파일 업로드
import warnings
warnings.filterwarnings('ignore')
!ls -l
import pandas as pd
SDF = pd.read_csv('seoulCCTV.csv', encoding = 'utf-8')
SDF.head()
1-2. column 이름 변경
SDF.columns # 열(column) 이름 확인
SDF.rename(columns = {SDF.columns[0] : '구별'}, inplace = True)
# 첫번째 열 이름 변경('기관명' -> '구별')
SDF.head()
1-3. 데이터 현황 파악
SDF.sort_values(by = '소계', ascending = True).head(7)
# 소계 오름차순 정렬
# SDF.sort_values(by = '소계', ascending = False).head(7)
# 소계 내림차순 정렬
1-4. column 추가
SDF['최근증가율'] = ((SDF['2016년'] + SDF['2015년'] + SDF['2014년']) / SDF['2013년도 이전']) * 100
SDF
SDF.sort_values(by = '최근증가율', ascending = False).head(7)
# '최근증가율' 열로 내림차순 정렬
2.'seoulPopulation.xls' 파일 전처리
2-1. 파일 업로드
import pandas as pd
SDFP = pd.read_excel('seoulPopulation.xls',
header = 2,
usecols = 'B, D, G, J, N')
# encoding = 'UTF-8')
SDFP.head()
2-2. Column명 변경
SDFP.rename(columns={SDFP.columns[0] : '구별',
SDFP.columns[1] : '인구수',
SDFP.columns[2] : '한국인',
SDFP.columns[3] : '외국인',
SDFP.columns[4] : '고령자'}, inplace=True)
SDFP.head()
2-3. 데이터 현황 파악
SDFP.drop([0], inplace = True) #'합계' 행(Row) 삭제
SDFP.head()
SDFP['구별'].unique()
#'구별' 열의 unique 정보 확인
SDFP[SDFP['구별'].isnull()]
#NaN 정보 확인
SDFP.tail()
SDFP.drop([26], inplace = True) #NaN 행 삭제
SDFP.tail()
SDFP['외국인비율'] = SDFP['외국인'] / SDFP['인구수'] * 100
SDFP['고령자비율'] = SDFP['고령자'] / SDFP['인구수'] * 100
SDFP.head()
- '외국인비율'과 '고령자비율' 열(Column)을 계산 후 추가
SDFP.sort_values(by = '인구수', ascending = False).head(7)
# '인구수' 내림차순 정렬
SDFP.sort_values(by = '외국인', ascending = False).head(7)
#'외국인' 내림차순 정렬
SDFP.sort_values(by = '외국인비율', ascending = False).head(7)
#'외국인비율' 내림차순 정렬
3. 두 데이터 합치기
3-1. 두 데이터프레임에 공통으로 있는 '구별'로 merge
DF = pd.merge(SDF, SDFP, on = '구별')
DF.head()
3-2. 불필요한 Column 삭제
del DF['2013년도 이전']
del DF['2014년']
del DF['2015년']
del DF['2016년']
DF.head()
3-3. '구별'을 index로 지정
DF.set_index('구별', inplace = True)
DF.head()
3-4. 상관계수
- 범위 : -1 ~ 1(0이면 관계없음)
- '고령자비율' vs. '소계'
import numpy as np
print(np.corrcoef(DF['고령자비율'], DF['소계']))
print(np.corrcoef(DF['외국인비율'], DF['소계']))
print(np.corrcoef(DF['인구수'], DF['소계']))
3-5. CCTV 개수와 '인구수'의 관계
DF.sort_values(by = '소계', ascending = False).head()
#'소계'(CCTV 개수) 내림차순 정렬
DF.sort_values(by='인구수', ascending=False).head()
#'인구수' 내림차순 정렬
4.Visualization
4-1. 막대그래프
import matplotlib.pyplot as plt
DF['소계'].plot(kind = 'barh', grid = True, figsize = (10, 10))
plt.show()
DF['소계'].sort_values().plot(kind = 'barh', grid = True, figsize = (10, 10))
plt.show()
#정렬 - sort_value( )
DF['CCTV비율'] = DF['소계'] / DF['인구수'] * 100
#'인구수' 대비 CCTV비율 계산 후 정렬하여 시각화
DF['CCTV비율'].sort_values().plot(kind = 'barh', grid = True, figsize = (10, 10))
plt.show()
4-2. 산점도
plt.figure(figsize=(6,6))
plt.scatter(DF['인구수'], DF['소계'], s = 50)
plt.xlabel('인구수')
plt.ylabel('CCTV')
plt.grid()
plt.show()
4-3. 회귀계수 계산
import numpy as np
np.set_printoptions(suppress = True)
fp1 = np.polyfit(DF['인구수'], DF['소계'], 1) #'소계' ~ '인구수'
fp1
array([ 0.00130916, 645.06649658])
f1 = np.poly1d(fp1)
print(f1, '\n')
fx = np.linspace(100000, 700000, 100)
print(fx)
#x축, y축 데이터 계산
4-4. 회귀선 추가
plt.figure(figsize = (10, 10))
plt.scatter(DF['인구수'], DF['소계'], s = 50)
plt.plot(fx, f1(fx), ls = 'dashed', lw = 3, color = 'g')
plt.xlabel('인구수')
plt.ylabel('CCTV')
plt.grid()
plt.show()
4-5. '오차' Column 추가 후 시각화
fp1 = np.polyfit(DF['인구수'], DF['소계'], 1)
f1 = np.poly1d(fp1)
fx = np.linspace(100000, 700000, 100)
DF['오차'] = np.abs(DF['소계'] - f1(DF['인구수']))
df_sort = DF.sort_values(by = '오차', ascending = False)
DF
# 최종 시각화
plt.figure(figsize = (14, 10))
plt.scatter(DF['인구수'], DF['소계'], c = DF['오차'], s = 50)
plt.plot(fx, f1(fx), ls = 'dashed', lw = 3, color = 'g')
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()
728x90