데이터분석/실습

서울시 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