프로젝트 - 서울시 CCTV 현황 분석(2)

이상해씨·2021년 9월 16일
0

EDA, 웹크롤링

목록 보기
3/13

◾데이터 확인

import pandas as pd

1. CCTV 데이터 확인

  • 데이터 읽기 및 컬럼명 변경
CCTV_Seoul = pd.read_csv("../data/01. Seoul_CCTV.csv", encoding="utf-8")
CCTV_Seoul.rename(columns={CCTV_Seoul.columns[0] : "구별"}, inplace=True)
CCTV_Seoul.head()

  • 최근 증가율 컬럼 추가
    • 2013년도 이전과 비교하여 2014, 2015, 2016년도 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)

2. 인구 데이터 확인

  • 데이터 읽기 및 컬럼명 변경
pop_Seoul = pd.read_excel(
    "../data/01. Seoul_Population.xls", header=2, usecols="B, D, G, J, N"
)
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()

  • 첫 행인 '합계' 행은 필요없으므로 삭제
  • unique 함수 : 중복 제외 데이터 확인 가능
    • 데이터 양이 많아지면 초반 검증을 위해 사용
  • 외국인, 고령자 비율 추가
pop_Seoul["외국인 비율"] = pop_Seoul["외국인"] / pop_Seoul["인구수"] * 100
pop_Seoul["고령자 비율"] = pop_Seoul["고령자"] / pop_Seoul["인구수"] * 100
pop_Seoul.head()


◾데이터 병합

1. 데이터 병합 기초

  • pd.concat()
  • pd.join()
  • pd.merge()
  • merge를 이용해 데이터 병합
    • DataFrame끼리 병합이 빈번하므로 꼬이지않게 주의
    • 두 데이터 프레임에서 컬럼이나 인덱스를 기준으로 병합
    • 기준이 되는 컬럼이나 인덱스를 라고 한다
    • 기준이 되는 키 값은 두 데이터 프레임에 모두 포함되어 있어야한다.
  • 테스트 데이터
left = pd.DataFrame(
    {
        "Key" : ["K0", "K4", "K2", "K3"],
        "A" : ["A0","A1","A2","A3"],
        "B" : ["B0","B1","B2","B3"]
    }
)

right = pd.DataFrame([
   {"Key":"K0", "C":"C0", "D":"D0"}, 
   {"Key":"K1", "C":"C1", "D":"D1"},
   {"Key":"K2", "C":"C2", "D":"D2"},
   {"Key":"K3", "C":"C3", "D":"D3"},
])
  • merge(df1, df2, on = '컬럼') : df1, df2를 '컬럼'을 기준으로 병합
    • on의 칼럼을 기준으로 공통된 값을 가지는 경우만 병합
  • merge(df1, df2, how="df1", on = '컬럼')
    • how의 df1에 on의 컬럼을 기준으로 df2 병합
    • df2의 값이 없는 경우 NaN을 추가
  • merge(df1, df2, how="outer", on = '컬럼')
    • df1, df2의 모든 데이터를 on의 컬럼을 기준으로 병합
    • 값이 없는 경우 NaN을 추가
  • merge(df1, df2, how="inner", on = '컬럼')
    • 기본적인 동작과 동일하게 값이 두 df에 있는 경우만 병합

2. CCTV, 인구 데이터 병합

  • 컬럼 : 구별을 이용하여 병합
    • 두 데이터 프레임에서 해당 컬럼은 일치하므로 how를 사용하지 않아도 된다.
  • 사용하지 않는 컬럼 제거 : 2013년 이전, 2014년, 2015년, 2016년
del data_result["2013년도 이전"]
del data_result["2014년"]
del data_result["2015년"]
del data_result["2016년"]
  • 인덱스 변경
    • 기본 인덱스는 행 번호로 구성
    • 인덱스는 중복값이 없어야 한다.(unique 명령으로 확인)
    • 현재 데이터에서는 구별 컬럼이 unique이므로 해당 컬럼으로 인덱스 변경
      • set_index : 인덱스 재지정

3. 상관관계

  • 이 프로젝트의 주제는 인구대비 상대적으로 CCTV가 적은 구를 찾는 것
  • 인구 데이터와 CCTV는 상관관계가 있는가?
  • 상관관계 : 두 변량 사이에 한쪽이 증가하면 다른 쪽도 증가(또는 감소)하는 경향이 있을 때, 두 변량 사이에 상관관계가 있다고 한다.
    • 단, 상관관계가 있다하여 두 변량이 인과관계인 것은 아니다.
    • 절대값 0.2이하 : 상관관계가 없거나 무시해도 좋은 수준
    • 절대값 0.4이하 : 약한 상관관계
    • 절대값 0.6이상 : 강한 상관관계
  • corr() : correlation의 축약형으로 상관관계를 계산하는 함수
    • Pandas에서 상관관계를 계산하는 함수
    • 상관계수를 조사해 0.2 이상의 데이터를 비교
    • 약한 상관관계이긴 하지만 의미가 있으므로 인구대비 CCTV 현황을 분석하여 상대적으로 CCTV가 적거나 많은 구를 찾는 것은 의미를 가진다.
  • 인구수 대비 CCTV 비율 추가
data_result["CCTV 비율"] = data_result["소계"] / data_result["인구수"] * 100
# CCTV 비율 높은 순 정렬
data_result.sort_values(by="CCTV 비율", ascending=False).head(5)


◾Matplotlib

  • 파이썬의 대표 시각화 도구
  • import matplotlib.pyplot as plt 로 많이 사용
  • Juypter NoteBook의 경우 결과가 out session에 나타난다.
  • %matplotlib inline 옵션을 사용 : 결과창을 새 창에 열지 않고 현재 Jupyter Notebook 창에 출력
import pandas as pd
# matlab의 기능을 담아둔 것이 pyplot
import matplotlib.pyplot as plt
%matplotlib inline
# get_ipython().run_line_magic("matplotlib", "inline")
  • matplotlib 기본 형태
    • plt.figure() : 그래프에 대한 속성 설정
    • plt.plot([가로축], [세로축]) : 세로축, 가로축의 데이터 설정
    • plt.show() : 결과 출력
  • 삼각함수 그리기
    • numpy의 sin() 사용
      • np.arange(a,b,s) : a부터 b까지의 s간격의 데이터
      • np.sin(value) : 사인 함수
import numpy as np

t = np.arange(0, 12, 0.01)
def drawGraph():
    plt.figure(figsize=(10, 6))
# label : 해당 그래프의 이름
    plt.plot(t, np.sin(t), label='sin')
    plt.plot(t, np.cos(t), label="cos")
# grid : 그래프에 격자 표시
    plt.grid()
# legend : plot의 label 표시
    plt.legend(loc="upper right")
# xlabel : x축의 제목
    plt.xlabel("time")
# ylabel : y축의 제목
    plt.ylabel("Amplitude")
# title : 전체 그래프의 제목
    plt.title("Example of sinewave")
    plt.show()

  • 추가 실습
t = np.arange(0, 5, 0.5)

def drawGraph():
    plt.figure(figsize=(10,6))
    # r-- : r은 빨간색, --은 점선
    plt.plot(t, t, "r--")
    # bs : b는 파랑색, s는 사각형
    plt.plot(t, t ** 2, "bs")
    # g^ : g는 초록색, ^는 위 방향 화살표
    plt.plot(t, t ** 3, "g^")
    plt.show()

  • 다양한 스타일 지정
t = [0, 1, 2, 3, 4, 5, 6]
y = [1, 4, 5, 8, 9, 5, 3]

def drawGraph():
    plt.figure(figsize=(10,6))
    plt.plot(
        # x축
        t,
        # y축
        y,
        # 그래프 색상
        color = "green",
        # 그래프 스타일
        linestyle="dashed",
        # 마커 스타일
        marker="o",
        # 마커 색상
        markerfacecolor="blue",
        # 마커 사이즈
        markersize=12,
    )
    # x축과 y축의 범위 지정
    plt.xlim([-0.5, 6.5])
    plt.ylim([0.5,9.5])
    plt.show()

  • scatter() : 점 그래프
# scatter는 점을 뿌리듯이 그리는 그래프
t = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
y = np.array([9, 8, 7, 9, 8, 3, 2, 4, 3, 4])

def drawGraph():
    plt.figure(figsize=(10, 6))
    plt.scatter(t, y)
    plt.show()

  • colormap : 값에 따라 색상 다르게 적용
colormap = t

def drawGraph():
    plt.figure(figsize=(10, 6))
    # marker : 점의 모양
    plt.scatter(t, y, s=50, c=colormap, marker=">")
    # colormap의 색상을 막대 그래프로 출력
    plt.colorbar()
    plt.show()

profile
후라이드 치킨

0개의 댓글