ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 서울특별시 구별 CCTV 현황 분석
    Python 2018. 2. 10. 22:14

    01서울시 구별 CCTV 현황 분석.ipynb


    [출처] 파이썬으로 데이터 주무르기, 민형기 지음, BJPublic, p23 ~ 72

    In [70]:
    # 패키지 로딩하기
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib import font_manager, rc
    %matplotlib inline
    
    In [3]:
    # csv 데이터 불러오기
    cctv_seoul = pd.read_csv("01. CCTV_in_Seoul.csv", encoding = "UTF-8")
    
    In [5]:
    # 데이터의 일부 보기
    cctv_seoul.head()
    
    Out[5]:
    기관명 소계 2013년도 이전 2014년 2015년 2016년
    0 강남구 2780 1292 430 584 932
    1 강동구 773 379 99 155 377
    2 강북구 748 369 120 138 204
    3 강서구 884 388 258 184 81
    4 관악구 1496 846 260 390 613
    In [6]:
    # 데이터의 변수명 보기
    cctv_seoul.columns
    
    Out[6]:
    Index(['기관명', '소계', '2013년도 이전', '2014년', '2015년', '2016년'], dtype='object')
    In [7]:
    # 첫 번째 변수명 보기
    cctv_seoul.columns[0]
    
    Out[7]:
    '기관명'
    In [10]:
    # 변수명 변경하기
    cctv_seoul.rename(columns = {cctv_seoul.columns[0] : "구별"}, inplace = True)
    cctv_seoul.head()
    
    Out[10]:
    구별 소계 2013년도 이전 2014년 2015년 2016년
    0 강남구 2780 1292 430 584 932
    1 강동구 773 379 99 155 377
    2 강북구 748 369 120 138 204
    3 강서구 884 388 258 184 81
    4 관악구 1496 846 260 390 613
    In [52]:
    # excel 데이터 불러오기
    pop_seoul = pd.read_excel("01. population_in_Seoul.xls", encoding="UTF-8")
    pop_seoul.head()
    
    Out[52]:
    기간 자치구 세대 인구 인구.1 인구.2 인구.3 인구.4 인구.5 인구.6 인구.7 인구.8 세대당인구 65세이상고령자
    0 기간 자치구 세대 합계 합계 합계 한국인 한국인 한국인 등록외국인 등록외국인 등록외국인 세대당인구 65세이상고령자
    1 기간 자치구 세대 남자 여자 남자 여자 남자 여자 세대당인구 65세이상고령자
    2 2017.1/4 합계 4202888 10197604 5000005 5197599 9926968 4871560 5055408 270636 128445 142191 2.36 1321458
    3 2017.1/4 종로구 72654 162820 79675 83145 153589 75611 77978 9231 4064 5167 2.11 25425
    4 2017.1/4 중구 59481 133240 65790 67450 124312 61656 62656 8928 4134 4794 2.09 20764
    In [53]:
    # excel 데이터 불러오기
    pop_seoul = pd.read_excel("01. population_in_Seoul.xls", 
                              encoding = "UTF-8",
                              header = 2,
                              parse_cols = "B, D, G, J, N")
    pop_seoul.head()
    
    C:\Users\buill\Anaconda3\envs\deep\lib\site-packages\ipykernel_launcher.py:5: FutureWarning: the 'parse_cols' keyword is deprecated, use 'usecols' instead
      """
    
    Out[53]:
    자치구 계.1 계.2 65세이상고령자
    0 합계 10197604.0 9926968.0 270636.0 1321458.0
    1 종로구 162820.0 153589.0 9231.0 25425.0
    2 중구 133240.0 124312.0 8928.0 20764.0
    3 용산구 244203.0 229456.0 14747.0 36231.0
    4 성동구 311244.0 303380.0 7864.0 39997.0
    In [54]:
    # 변수명 변경하기
    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()
    
    Out[54]:
    구별 인구수 한국인 외국인 고령자
    0 합계 10197604.0 9926968.0 270636.0 1321458.0
    1 종로구 162820.0 153589.0 9231.0 25425.0
    2 중구 133240.0 124312.0 8928.0 20764.0
    3 용산구 244203.0 229456.0 14747.0 36231.0
    4 성동구 311244.0 303380.0 7864.0 39997.0
    In [16]:
    # 행 이름
    pop_seoul.index
    
    Out[16]:
    RangeIndex(start=0, stop=27, step=1)
    In [17]:
    # 데이터의 정보
    pop_seoul.info()
    
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 27 entries, 0 to 26
    Data columns (total 5 columns):
    구별     26 non-null object
    인구수    26 non-null float64
    한국인    26 non-null float64
    외국인    26 non-null float64
    고령자    26 non-null float64
    dtypes: float64(4), object(1)
    memory usage: 1.1+ KB
    
    In [18]:
    # 기술통계량 구하기
    pop_seoul.describe()
    
    Out[18]:
    인구수 한국인 외국인 고령자
    count 2.600000e+01 2.600000e+01 26.000000 2.600000e+01
    mean 7.844311e+05 7.636129e+05 20818.153846 1.016506e+05
    std 1.924156e+06 1.873421e+06 51598.169516 2.491801e+05
    min 1.332400e+05 1.243120e+05 2017.000000 2.076400e+04
    25% 3.348055e+05 3.316718e+05 4489.000000 4.831200e+04
    50% 4.135115e+05 4.051690e+05 9079.500000 5.439750e+04
    75% 4.907855e+05 4.864445e+05 14901.500000 6.431075e+04
    max 1.019760e+07 9.926968e+06 270636.000000 1.321458e+06
    In [21]:
    # 정렬하기 : 내림차순
    pop_seoul.sort_values(by = "인구수", ascending = False)
    
    Out[21]:
    구별 인구수 한국인 외국인 고령자
    0 합계 10197604.0 9926968.0 270636.0 1321458.0
    24 송파구 667483.0 660584.0 6899.0 72506.0
    16 강서구 603772.0 597248.0 6524.0 72548.0
    23 강남구 570500.0 565550.0 4950.0 63167.0
    11 노원구 569384.0 565565.0 3819.0 71941.0
    21 관악구 525515.0 507203.0 18312.0 68082.0
    12 은평구 494388.0 489943.0 4445.0 72334.0
    15 양천구 479978.0 475949.0 4029.0 52975.0
    8 성북구 461260.0 449773.0 11487.0 64692.0
    25 강동구 453233.0 449019.0 4214.0 54622.0
    22 서초구 450310.0 445994.0 4316.0 51733.0
    17 구로구 447874.0 416487.0 31387.0 56833.0
    7 중랑구 414503.0 409882.0 4621.0 56774.0
    20 동작구 412520.0 400456.0 12064.0 56013.0
    19 영등포구 402985.0 368072.0 34913.0 52413.0
    14 마포구 389649.0 378566.0 11083.0 48765.0
    5 광진구 372164.0 357211.0 14953.0 42214.0
    6 동대문구 369496.0 354079.0 15417.0 54173.0
    10 도봉구 348646.0 346629.0 2017.0 51312.0
    9 강북구 330192.0 326686.0 3506.0 54813.0
    13 서대문구 327163.0 314982.0 12181.0 48161.0
    4 성동구 311244.0 303380.0 7864.0 39997.0
    18 금천구 255082.0 236353.0 18729.0 32970.0
    3 용산구 244203.0 229456.0 14747.0 36231.0
    1 종로구 162820.0 153589.0 9231.0 25425.0
    2 중구 133240.0 124312.0 8928.0 20764.0
    26 NaN NaN NaN NaN NaN
    In [22]:
    # 특정 변수만 불러오기
    pop_seoul["인구수"]
    
    Out[22]:
    0     10197604.0
    1       162820.0
    2       133240.0
    3       244203.0
    4       311244.0
    5       372164.0
    6       369496.0
    7       414503.0
    8       461260.0
    9       330192.0
    10      348646.0
    11      569384.0
    12      494388.0
    13      327163.0
    14      389649.0
    15      479978.0
    16      603772.0
    17      447874.0
    18      255082.0
    19      402985.0
    20      412520.0
    21      525515.0
    22      450310.0
    23      570500.0
    24      667483.0
    25      453233.0
    26           NaN
    Name: 인구수, dtype: float64
    In [23]:
    # 일부의 행만 불러오기
    pop_seoul[0:3]
    
    Out[23]:
    구별 인구수 한국인 외국인 고령자
    0 합계 10197604.0 9926968.0 270636.0 1321458.0
    1 종로구 162820.0 153589.0 9231.0 25425.0
    2 중구 133240.0 124312.0 8928.0 20764.0
    In [29]:
    # 하나의 열만 추출하기
    pop_seoul.loc[: , "구별"]
    
    Out[29]:
    0       합계
    1      종로구
    2       중구
    3      용산구
    4      성동구
    5      광진구
    6     동대문구
    7      중랑구
    8      성북구
    9      강북구
    10     도봉구
    11     노원구
    12     은평구
    13    서대문구
    14     마포구
    15     양천구
    16     강서구
    17     구로구
    18     금천구
    19    영등포구
    20     동작구
    21     관악구
    22     서초구
    23     강남구
    24     송파구
    25     강동구
    26     NaN
    Name: 구별, dtype: object
    In [30]:
    # 한 개 이상의 열을 추출하기
    pop_seoul.loc[: , ["구별", "인구수"]]
    
    Out[30]:
    구별 인구수
    0 합계 10197604.0
    1 종로구 162820.0
    2 중구 133240.0
    3 용산구 244203.0
    4 성동구 311244.0
    5 광진구 372164.0
    6 동대문구 369496.0
    7 중랑구 414503.0
    8 성북구 461260.0
    9 강북구 330192.0
    10 도봉구 348646.0
    11 노원구 569384.0
    12 은평구 494388.0
    13 서대문구 327163.0
    14 마포구 389649.0
    15 양천구 479978.0
    16 강서구 603772.0
    17 구로구 447874.0
    18 금천구 255082.0
    19 영등포구 402985.0
    20 동작구 412520.0
    21 관악구 525515.0
    22 서초구 450310.0
    23 강남구 570500.0
    24 송파구 667483.0
    25 강동구 453233.0
    26 NaN NaN
    In [34]:
    # 특정한 행과 특정한 열만 추출하기
    # 구별 열만 추출하기
    pop_seoul.loc[pop_seoul.구별 == "양천구", "인구수"]
    
    Out[34]:
    15    479978.0
    Name: 인구수, dtype: float64
    In [35]:
    # iloc를 이용한 특정한 행과 열을 추출하기
    pop_seoul.iloc[1:3, 2:4]
    
    Out[35]:
    한국인 외국인
    1 153589.0 9231.0
    2 124312.0 8928.0
    In [37]:
    # 데이터 복사하기
    pop_seoul2 = pop_seoul.copy()
    pop_seoul2.head()
    
    Out[37]:
    구별 인구수 한국인 외국인 고령자
    0 합계 10197604.0 9926968.0 270636.0 1321458.0
    1 종로구 162820.0 153589.0 9231.0 25425.0
    2 중구 133240.0 124312.0 8928.0 20764.0
    3 용산구 244203.0 229456.0 14747.0 36231.0
    4 성동구 311244.0 303380.0 7864.0 39997.0
    In [42]:
    # 구별에 용산구가 있는지를 확인
    pop_seoul["구별"].isin(["용산구"])
    
    Out[42]:
    0     False
    1     False
    2     False
    3      True
    4     False
    5     False
    6     False
    7     False
    8     False
    9     False
    10    False
    11    False
    12    False
    13    False
    14    False
    15    False
    16    False
    17    False
    18    False
    19    False
    20    False
    21    False
    22    False
    23    False
    24    False
    25    False
    26    False
    Name: 구별, dtype: bool
    In [44]:
    # 양적 자료인 열에 대한 누적합 구하기
    pop_seoul.iloc[:, 1:4].apply(np.cumsum)
    
    Out[44]:
    인구수 한국인 외국인
    0 10197604.0 9926968.0 270636.0
    1 10360424.0 10080557.0 279867.0
    2 10493664.0 10204869.0 288795.0
    3 10737867.0 10434325.0 303542.0
    4 11049111.0 10737705.0 311406.0
    5 11421275.0 11094916.0 326359.0
    6 11790771.0 11448995.0 341776.0
    7 12205274.0 11858877.0 346397.0
    8 12666534.0 12308650.0 357884.0
    9 12996726.0 12635336.0 361390.0
    10 13345372.0 12981965.0 363407.0
    11 13914756.0 13547530.0 367226.0
    12 14409144.0 14037473.0 371671.0
    13 14736307.0 14352455.0 383852.0
    14 15125956.0 14731021.0 394935.0
    15 15605934.0 15206970.0 398964.0
    16 16209706.0 15804218.0 405488.0
    17 16657580.0 16220705.0 436875.0
    18 16912662.0 16457058.0 455604.0
    19 17315647.0 16825130.0 490517.0
    20 17728167.0 17225586.0 502581.0
    21 18253682.0 17732789.0 520893.0
    22 18703992.0 18178783.0 525209.0
    23 19274492.0 18744333.0 530159.0
    24 19941975.0 19404917.0 537058.0
    25 20395208.0 19853936.0 541272.0
    26 NaN NaN NaN
    In [49]:
    # 양적 자료인 열에 대한 범위 구하기
    pop_seoul.iloc[:, 1:4].apply(lambda x: x.max() - x.min())
    
    Out[49]:
    인구수    10064364.0
    한국인     9802656.0
    외국인      268619.0
    dtype: float64
    In [55]:
    # 첫 행 제거하기
    pop_seoul.drop([0], inplace = True)
    pop_seoul.head()
    
    Out[55]:
    구별 인구수 한국인 외국인 고령자
    1 종로구 162820.0 153589.0 9231.0 25425.0
    2 중구 133240.0 124312.0 8928.0 20764.0
    3 용산구 244203.0 229456.0 14747.0 36231.0
    4 성동구 311244.0 303380.0 7864.0 39997.0
    5 광진구 372164.0 357211.0 14953.0 42214.0
    In [56]:
    # 구별 목록 보기
    pop_seoul["구별"].unique()
    
    Out[56]:
    array(['종로구', '중구', '용산구', '성동구', '광진구', '동대문구', '중랑구', '성북구', '강북구',
           '도봉구', '노원구', '은평구', '서대문구', '마포구', '양천구', '강서구', '구로구', '금천구',
           '영등포구', '동작구', '관악구', '서초구', '강남구', '송파구', '강동구', nan], dtype=object)
    In [57]:
    # NAN 추출하기
    pop_seoul[pop_seoul["구별"].isnull()]
    
    Out[57]:
    구별 인구수 한국인 외국인 고령자
    26 NaN NaN NaN NaN NaN
    In [58]:
    # 구별에 NAN을 포함하는 행 삭제하기
    pop_seoul.drop([26], inplace = True)
    pop_seoul.head()
    
    In [60]:
    # 새로운 변수 만들기
    pop_seoul["외국인비율"] = (pop_seoul["외국인"] / pop_seoul["인구수"])*100
    pop_seoul["고령자비율"] = (pop_seoul["고령자"] / pop_seoul["인구수"])*100
    pop_seoul.head()
    
    Out[60]:
    구별 인구수 한국인 외국인 고령자 외국인비율 고령자비율
    1 종로구 162820.0 153589.0 9231.0 25425.0 5.669451 15.615404
    2 중구 133240.0 124312.0 8928.0 20764.0 6.700690 15.583909
    3 용산구 244203.0 229456.0 14747.0 36231.0 6.038828 14.836427
    4 성동구 311244.0 303380.0 7864.0 39997.0 2.526635 12.850689
    5 광진구 372164.0 357211.0 14953.0 42214.0 4.017852 11.342849
    In [61]:
    # 인구수를 기준으로 내림차순으로 정렬하기
    pop_seoul.sort_values(by = "인구수", ascending = False)
    pop_seoul.head()
    
    Out[61]:
    구별 인구수 한국인 외국인 고령자 외국인비율 고령자비율
    1 종로구 162820.0 153589.0 9231.0 25425.0 5.669451 15.615404
    2 중구 133240.0 124312.0 8928.0 20764.0 6.700690 15.583909
    3 용산구 244203.0 229456.0 14747.0 36231.0 6.038828 14.836427
    4 성동구 311244.0 303380.0 7864.0 39997.0 2.526635 12.850689
    5 광진구 372164.0 357211.0 14953.0 42214.0 4.017852 11.342849
    In [62]:
    # CCTV와 인구 데이터 합치기
    seoul = pd.merge(cctv_seoul, pop_seoul, on = "구별")
    seoul.head()
    
    Out[62]:
    구별 소계 2013년도 이전 2014년 2015년 2016년 인구수 한국인 외국인 고령자 외국인비율 고령자비율
    0 강남구 2780 1292 430 584 932 570500.0 565550.0 4950.0 63167.0 0.867660 11.072217
    1 강동구 773 379 99 155 377 453233.0 449019.0 4214.0 54622.0 0.929765 12.051638
    2 강북구 748 369 120 138 204 330192.0 326686.0 3506.0 54813.0 1.061806 16.600342
    3 강서구 884 388 258 184 81 603772.0 597248.0 6524.0 72548.0 1.080540 12.015794
    4 관악구 1496 846 260 390 613 525515.0 507203.0 18312.0 68082.0 3.484582 12.955291
    In [65]:
    # 특정한 열 삭제하기
    del seoul["2013년도 이전"]
    del seoul["2014년"]
    del seoul["2015년"]
    del seoul["2016년"]
    seoul.head()
    
    Out[65]:
    구별 소계 인구수 한국인 외국인 고령자 외국인비율 고령자비율
    0 강남구 2780 570500.0 565550.0 4950.0 63167.0 0.867660 11.072217
    1 강동구 773 453233.0 449019.0 4214.0 54622.0 0.929765 12.051638
    2 강북구 748 330192.0 326686.0 3506.0 54813.0 1.061806 16.600342
    3 강서구 884 603772.0 597248.0 6524.0 72548.0 1.080540 12.015794
    4 관악구 1496 525515.0 507203.0 18312.0 68082.0 3.484582 12.955291
    In [66]:
    # 기준 세팅하기
    seoul.set_index("구별", inplace = True)
    seoul.head()
    
    Out[66]:
    소계 인구수 한국인 외국인 고령자 외국인비율 고령자비율
    구별
    강남구 2780 570500.0 565550.0 4950.0 63167.0 0.867660 11.072217
    강동구 773 453233.0 449019.0 4214.0 54622.0 0.929765 12.051638
    강북구 748 330192.0 326686.0 3506.0 54813.0 1.061806 16.600342
    강서구 884 603772.0 597248.0 6524.0 72548.0 1.080540 12.015794
    관악구 1496 525515.0 507203.0 18312.0 68082.0 3.484582 12.955291
    In [67]:
    # 상관계수 구하기
    np.corrcoef(seoul["고령자비율"], seoul["소계"])
    
    Out[67]:
    array([[ 1.        , -0.28078554],
           [-0.28078554,  1.        ]])
    In [68]:
    # 상관계수 구하기
    np.corrcoef(seoul["외국인비율"], seoul["소계"])
    
    Out[68]:
    array([[ 1.        , -0.13607433],
           [-0.13607433,  1.        ]])
    In [69]:
    # 상관계수 구하기
    np.corrcoef(seoul["인구수"], seoul["소계"])
    
    Out[69]:
    array([[ 1.        ,  0.30634228],
           [ 0.30634228,  1.        ]])
    In [84]:
    # 가로막대 그래프
    font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()
    rc('font', family=font_name)
    seoul["소계"].plot(kind = "barh", grid = True, figsize = (10, 10))
    plt.show()
    
    In [85]:
    # 가로막대 그래프
    seoul["소계"].sort_values().plot(kind = "barh", grid = True, figsize = (10, 10))
    plt.show()
    
    In [86]:
    seoul["CCTV비율"] = (seoul["소계"] / seoul["인구수"])*100
    seoul["CCTV비율"].sort_values().plot(kind = "barh", grid = True, figsize = (10, 10))
    plt.show()
    
    In [90]:
    # 산점도 작성하기
    plt.figure(figsize = (10, 10))
    plt.scatter(seoul["인구수"], seoul["소계"], s = 50)
    plt.xlabel("인구수")
    plt.ylabel("CCTV")
    plt.grid()
    plt.show()
    
    In [92]:
    fp1 = np.polyfit(seoul["인구수"], seoul["소계"], 1)
    f1 = np.poly1d(fp1)
    fx = np.linspace(100000, 700000, 100)
    
    In [93]:
    plt.figure(figsize = (10, 10))
    plt.scatter(seoul["인구수"], seoul["소계"], s = 50)
    plt.plot(fx, f1(fx), ls = "dashed", lw = 3, color = "g")
    plt.xlabel("인구수")
    plt.ylabel("CCTV")
    plt.grid()
    plt.show()
    
    In [94]:
    fp1 = np.polyfit(seoul["인구수"], seoul["소계"], 1)
    f1 = np.poly1d(fp1)
    fx = np.linspace(100000, 700000, 100)
    
    seoul["오차"] = np.abs(seoul["소계"] - f1(seoul["인구수"]))
    seoul_sort = seoul.sort_values(by = "오차", ascending = False)
    seoul_sort.head()
    
    Out[94]:
    소계 인구수 한국인 외국인 고령자 외국인비율 고령자비율 CCTV비율 오차
    구별
    강남구 2780 570500.0 565550.0 4950.0 63167.0 0.867660 11.072217 0.487292 1388.055355
    송파구 618 667483.0 660584.0 6899.0 72506.0 1.033584 10.862599 0.092587 900.911312
    양천구 2034 479978.0 475949.0 4029.0 52975.0 0.839413 11.036964 0.423769 760.563512
    서초구 1930 450310.0 445994.0 4316.0 51733.0 0.958451 11.488308 0.428594 695.403794
    용산구 1624 244203.0 229456.0 14747.0 36231.0 6.038828 14.836427 0.665020 659.231690
    In [95]:
    plt.figure(figsize = (10, 10))
    plt.scatter(seoul["인구수"], seoul["소계"], c = seoul["오차"], s = 50)
    plt.plot(fx, f1(fx), ls = "dashed", lw = 3, color = "g")
    
    for n in range(10):
        plt.text(seoul_sort["인구수"][n]*1.02, seoul_sort["소계"][n]*0.98, seoul_sort.index[n], fontsize = 15)
    
    plt.xlabel("인구수")
    plt.ylabel("CCTV")
    plt.colorbar()
    plt.grid()
    plt.show()
    

    01서울시 구별 CCTV 현황 분석


    'Python' 카테고리의 다른 글

    seaborn 패키지를 이용한 상자그림(Boxplot) 작성하기  (0) 2018.02.19
    %matplotlib inline  (0) 2018.02.19
    문자열(string)  (0) 2018.02.10
    python기초  (0) 2018.01.31
    Python으로 Big Data 분석하기  (0) 2018.01.31
Designed by Tistory.