파이썬 이것저것/파이썬 데이터분석

[파이썬] 서울 CCTV 데이터 분석해보기

agingcurve 2022. 6. 4. 22:30
반응형

목표

1. 서울시 CCTV데이터를 정리하고 정렬하기

2. 그래프로 시각화 해보기

3. 전체적인 데이터 인사이트를 보기

4. 이상치를 강조해보기

 

사용데이터

서울시 자치구 연도별 CCTV 설치 현황 데이터를 불러와서 진행해봄 데이터는 13년이 이전 ~ 16년도 데이터를 사용해봄

 

import pandas as pd 
In [2]:
CCTV_Seoul = pd.read_csv("../data/01. Seoul_CCTV.csv")
CCTV_Seoul.head()
CCTV_Seoul.columns
Out[3]:
Index(['기관명', '소계', '2013년도 이전', '2014년', '2015년', '2016년'], dtype='object')
In [4]:
CCTV_Seoul.columns[0]
Out[4]:
'기관명'
In [5]:
CCTV_Seoul.rename(columns={CCTV_Seoul.columns[0]: "구별"}, inplace=True)
CCTV_Seoul.head()
  • 기관명을 구별로 바꾸기

 

pop_Seoul = pd.read_excel("../data/01. Seoul_Population.xls")
pop_Seoul.head()

pop_Seoul = pd.read_excel(
    "../data/01. Seoul_Population.xls", header=2, usecols="B, D, G, J, N")
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()

 

2. CCTV 데이터 훑어보기

# 기존 컬럼이 없으면 추가, 있으면 수정
CCTV_Seoul["최근증가율"] = (
    (CCTV_Seoul["2016년"] + CCTV_Seoul["2015년"] + CCTV_Seoul["2014년"]) / CCTV_Seoul["2013년도 이전"] * 100
)

CCTV_Seoul.sort_values(by="최근증가율", ascending=False).head(5)
 

3. 인구현황 데이터 훑어보기

pop_Seoul.head()

pop_Seoul["구별"].unique() 
Out[93]:
array(['종로구', '중구', '용산구', '성동구', '광진구', '동대문구', '중랑구', '성북구', '강북구',
       '도봉구', '노원구', '은평구', '서대문구', '마포구', '양천구', '강서구', '구로구', '금천구',
       '영등포구', '동작구', '관악구', '서초구', '강남구', '송파구', '강동구'], dtype=object)
# 외국인비율, 고령자비율 

pop_Seoul["외국인비율"] = pop_Seoul["외국인"] / pop_Seoul["인구수"] * 100
pop_Seoul["고령자비율"] = pop_Seoul["고령자"] / pop_Seoul["인구수"] * 100
pop_Seoul.head()

4: Pandas에서 plot 그리기

  • matplotlib 을 가져와서 사용합니다
data_result.head()

 

data_result["인구수"].plot(kind="bar", figsize=(10, 10));

 

data_result["인구수"].plot(kind="barh", figsize=(10, 10));

 

5. 데이터 시각화

import matplotlib.pyplot as plt 
# import matplotlib as mpl 
from matplotlib import rc

plt.rcParams["axes.unicode_minus"] = False # 마이너스 부호 때문에 한글이 깨질 수가 있어 주는 설정
rc("font", family="Arial Unicode MS") # Windows: Malgun Gothic 
# %matplotlib inline 
get_ipython().run_line_magic("matplotlib", "inline")
data_result["소계"].plot(kind="barh", grid=True, figsize=(10, 10));

def drawGraph():
    data_result["소계"].sort_values().plot(
        kind="barh", grid=True, title="가장 CCTV가 많은 구", figsize=(10, 10));
drawGraph()

CCTV비율 컬럼 시각화

def drawGraph():
    data_result["CCTV비율"].sort_values().plot(
        kind="barh", grid=True, title="가장 CCTV가 많은 구", figsize=(10, 10));
drawGraph()

인구수와 소계 컬럼으로 scatter plot 그리기

def drawGraph():
    
    plt.figure(figsize=(14, 10))
    plt.scatter(data_result["인구수"], data_result["소계"], s=50)
    plt.xlabel("인구수")
    plt.ylabel("CCTV")
    plt.grid(True)
    plt.show() 
drawGraph()

  • 인구가 40만인 구에서 서울시의 전체 경향에 맞는 적당한 CCTV 수는?
In [205]:
fx = np.linspace(100000, 700000, 100)
  • 경향선을 그리기 위한 X 데이터 생성
  • np.linspace(a, b, n): a부터 b까지 n개의 등간격 데이터 생성
In [213]:
def drawGraph():
    
    plt.figure(figsize=(14, 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(True)
    plt.show() 
drawGraph()

 

7. 강조하고 싶은 데이터를 시각화

  • 경향(trend)과의 오차를 만들자
  • 경향은 f1 함수에 해당 인구를 입력
  • f1(data_result["인구수"])
In [215]:
data_result.head(3)
fp1 = np.polyfit(data_result["인구수"], data_result["소계"], 1) f1 = np.poly1d(fp1) fx = np.linspace(100000, 700000, 100)

# 경향과 비교해서 데이터의 오차가 너무 나는 데이터를 계산 

df_sort_f = data_result.sort_values(by="오차", ascending=False) # 내림차순 
df_sort_t = data_result.sort_values(by="오차", ascending=True) # 오름차순   
# 경향 대비 CCTV를 많이 가진 구 
df_sort_f.head()

 

# 경향 대비 CCTV를 적게 가진 구 
df_sort_t.head()

 

from matplotlib.colors import ListedColormap

# colormap 을 사용자 정의(user define)로 세팅 
color_step = ["#e74c3c", "#2ecc71", "#95a9a6", "#2ecc71", "#3498db", "#3498db"]
my_cmap = ListedColormap(color_step)
In [245]:
def drawGraph():
    
    plt.figure(figsize=(14, 10))
    plt.scatter(data_result["인구수"], data_result["소계"], s=50, c=data_result["오차"], cmap=my_cmap)
    plt.plot(fx, f1(fx), ls="dashed", lw=3, color="g")

    for n in range(5):
        # 상위 5개 
        plt.text(
            df_sort_f["인구수"][n] * 1.02, # x 좌표
            df_sort_f["소계"][n] * 0.98,  # y 좌표
            df_sort_f.index[n], # title 
            fontsize=15,
        )
    
        # 하위 5개 
        plt.text(
            df_sort_t["인구수"][n] * 1.02, 
            df_sort_t["소계"][n] * 0.98,
            df_sort_t.index[n],
            fontsize=15
        )
        
    
    plt.xlabel("인구수")
    plt.ylabel("CCTV")
    plt.colorbar()
    plt.grid(True)
    plt.show() 
drawGraph()