데이터분석/미니프로젝트 06. 인구 분석

06-01. 인구소멸위기지역 파악하기 프로젝트 개요, 데이터 수집 및 정리

책다니엘 2024. 4. 21. 07:27

이번에는 현대 대한민국에 있어 매우 심각한 문제가 된 '인구소멸위기지역'을 조사하는 프로젝트이다. 먼저 인구소멸위기지역을 파악하고, 인구소멸위기지역을 지도로 표현한 다음, 카르토그램으로 표현하여, 인구별로 영역을 표시하도록 할 것이다.

 

1. 먼저 folium으로 그리기 위해 시도별 경계선이 있는 json파일을 구해야 한다. 문제는 앞서 서울시 범죄율을 파악하기 위해 받았던 Lucy Park님의 자료에는, 고유한 아이디 역할을 하는 것이 없다는 것이다.

name으로는 되어 있지만, 고유성을 띄는 id가 아니다

 

2. 따라서 이번에는 제로베이스 데이터스쿨에서 나눠준 자료를 기반으로 프로젝트를 진행한다. 강사분께서 친절히 id를 따로 작성하여 나눠 주셨다.

감사합니다!

3. 1,2번에서 알 수 있듯이 Folium을 활용하기 위한 json파일에는 ID가 필요하다. 인구현황 데이터에도 똑같이 ID가 필요할 것이다. 그래야 이후 카르토그램으로 그릴 때도 서로 다른 두 자료를 함께 활용할 수 있기 때문이다.

 

4. 인구현황데이터는 일반적으로 아래의 링크에서 얻는다.

https://kosis.kr/index/index.do

 

KOSIS 국가통계포털

내가 본 통계표 최근 본 통계표 25개가 저장됩니다. 닫기

kosis.kr

다만 데이터를 얻는 과정이 매우 달라서, 공부를 위한 소규모 프로젝트를 진행하기에는 데이터 수집 과정에서부터 무리가 있을 수 있다. 그래서 제로베이스 데이터스쿨에서 인구현황 데이터도 나누어주었다.

 

...하지만!

 

데이터분석가를 꿈꾸는 사람으로서 이런 인구통계데이터 수집부터 막힐 수 없다. 직접 사이트에 방문해 2022년 데이터를 얻어왔다.

세부 카테고리로 들어가고
카테고리를 선택하고 조회 레벨을 선택하고 고급 옵션에서 계층 컬럼 표시 부분도 선택하고
결과적으로 이런 데이터를 얻어 왔다!
이건 제로베이스 데이터스쿨에서 나눠준 데이터다. 똑같다!

5. 이제 데이터를 보고 어떻게 해석할 것인지 생각해본다. 먼저 분석을 위해 필요한 라이브러리들을 받아 온다.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import set_matplotlib_hangul

** 5번 프로젝트에서 만들었던 matplotlib 한글 세팅 모듈을 사용했다.

population = pd.read_excel('../data/07_population_raw_data(2022).xlsx', header=1)
population.fillna(method='pad', inplace=True)
population.head()

** fillna(method='pad')옵션을 통해 NaN이 있을 경우, 이전 값을 적용하도록 했다.(해당 옵션을 적용하지 않으니 지역명에서 NaN이 엄청 많이 떴다)

이런 결과를 얻어 온다.

 

 

6. 컬럼명도 바꿔 주자.

population.rename(columns = {'행정구역별(읍면동)(1)':'광역시도', '행정구역별(읍면동)(2)': '시도', '합계':'인구수'}, inplace=True)
population.head()

 

7. '소계'라는 컬럼은 필요 없으니 빼 준다.

population = population[(population['시도'] != '소계')]
population.head()

 

8. '항목' 컬럼을 '구분'으로 바꿔주고, 매 구마다 3개씩 있는 '총인구(명)' 등의 컬럼을 단순화해주었다.

population.is_copy = False

population.rename(columns = {'항목':'구분'}, inplace=True)

population.loc[population['구분'] == '총인구(명)', '구분'] = '합계'
population.loc[population['구분'] == '총인구_남자(명)', '구분'] = '남자'
population.loc[population['구분'] == '총인구_여자(명)', '구분'] = '여자'

population.head()

** pandas의 조건문이 없었다면 for문을 돌렸어야 했을 것이다. 매우 유익한 pandas의 개발자 분들에게 감사를!

 

9. '인구소멸위기지역' 계산식의 변수에는 '가임기여성의 수'와 '노인인구의 수'가 들어간다. 현재 데이터에는 해당 내용이 없기에, 컬럼을 더하여 필요한 컬럼을 만들어주었다.

int가 아닌 컬럼을 발견하고

# pd.to_numeric으로 숫자형이 아닌 값은 전부 NaN으로 바꾼 다음 fillna로 0으로 만들어준다.
population['95~99세'] = pd.to_numeric(population['95~99세'], errors='coerce').fillna(0)
population['100세이상'] = pd.to_numeric(population['100세이상'], errors='coerce').fillna(0)

 

인구소멸지수는 20~39세 여성인구수 / 65세 이상 고령인구수로 계산하므로

population['20~39세'] = (population['20~24세'] + 
                       population['25~29세'] + 
                       population['30~34세'] + 
                       population['35~39세'] )
population['65세이상'] = (population['65~69세'] + 
                       population['70~74세'] + 
                       population['75~79세'] + 
                       population['80~84세'] + 
                       population['85~89세'] + 
                       population['90~94세'] + 
                       population['95~99세'] + 
                       population['100세이상'] )

population.head()

필요한 컬럼을 만들어주었다.

 

10. 이제 데이터를 좀 더 보기 쉽게 바꿔 보자. 열에는 지역 구분이 들어가도록, 행에는 성별, 연령별로 표시하도록 해보고 싶다. pivot_table을 이용하면 이 작업을 매우 쉽게 할 수 있다.

pop = pd.pivot_table(population, index=['광역시도', '시도'], columns=['구분'], values=['인구수', '20~39세', '65세이상'])
pop

 

11. 좀 더 편집을 해보자. 이제 '인구소멸위험지수'를 계산해보자. 

pop['인구소멸위험지수'] = pop['20~39세', '여자'] / pop['65세이상','합계']
pop.head()

 

12. 그 다음엔 인구소멸위험지수를 바탕으로 '인구소멸위험지역'을 만들어보자.

pop['인구소멸위기지역'] = pop['인구소멸위험지수'] < 0.5
pop

강원도 5개지역은 전부 인구소멸위기지역이다...!

13. 인구소멸위기지역을 바로 조회해보자. 

pop[pop['인구소멸위기지역'] == True].index.get_level_values(1)

# Index(['강릉시', '고성군', '동해시', '삼척시', '속초시', '양구군', '양양군', '영월군', '인제군', '정선군',
#       ...
#       '태안군', '홍성군', '괴산군', '단양군', '보은군', '영동군', '옥천군', '음성군', '제천시', '충주시'],
#      dtype='object', name='시도', length=115)

 

** 인구소멸위기지역이 총 115개지역이다. 참고로 이 데이터프레임 내의 '시도'의 총 갯수는 237개이다.

pop.index.get_level_values(1).unique()

# Index(['강릉시', '고성군', '동해시', '삼척시', '속초시', '양구군', '양양군', '영월군', '원주시', '인제군',
#       ...
#       '영동군', '옥천군', '음성군', '제천시', '증평군', '진천군', '청원구', '청주시', '충주시', '흥덕구'],
#      dtype='object', name='시도', length=237)

 

대한민국 시군구의 절반이 인구소멸위기지역이라니... 인구소멸위기가 코앞으로 다가온 것이 느껴진다. 참고로 제로베이스 데이터스쿨에서 제공해준 2016년의 자료에 따르면 인구소멸위기지역은 83개이다! 고작 8년만에 인구소멸지역이 32개나 증가한 것이다!

 

14. 이제 reset_index로 인덱스를 초기화하자.

pop.reset_index(inplace=True)
pop

 

15. 두 줄로 되어 있는 컬럼명도 합쳐 주자.

tmp_columns = [
    pop.columns.get_level_values(0)[n] + pop.columns.get_level_values(1)[n]
    for n in range(0, len(pop.columns.get_level_values(0)))
]

pop.columns = tmp_columns
pop