제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.20]

[강의 요약]

[Part 04. EDA/웹 크롤링/파이썬 프로그래밍_ Ch 08. 인구 분석] 강의 수강

클립 01~12까지 강의 수강하였음

🐢 100일 챌린지 🔥 : [▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰░                                       ] 65/100일 (65%)

 

 

 

[클립 01~12까지 정리]

▶ 지방 인구 소멸위기 분석 프로젝트

이걸 갑자기 왜 분석할까?

대한민국의 많은 군 단위 지역은 인구가 줄고 있고

특히 20~30대 여성 인구가 줄어드는 곳은 장기적으로 지역 존립 자체가 위태로워진다고 한다.

정부나 언론에서는 이런 지역을 “소멸위험지역”이라고 부르며 기준을 제시한다.

 

“해당 지역의 20~39세 여성 인구수를 65세 이상 고령 인구수로 나눈 값이 0.5보다 작으면 소멸위험지역이다.”

 

사용 데이터 출처 :  https://kosis.kr/index/index.do

엑셀로 제공되는 행정구역 단위 인구 통계 파일 사용

 

 

▶ 1. 데이터 불러오기와 전처리

[엑셀 파일 읽는 코드]

import pandas as pd

df = pd.read_excel("07. population_raw_data.xlsx", header=1)
df.head()
  • header=1 : 두 번째 줄부터 실제 헤더가 시작됨
  • 출력하면 '행정구역(동읍면)별', '항목', '2022년 총인구수', ... 등의 컬럼이 있다.

 

[지역 이름 정리 코드]

df = df.rename(columns={"행정구역(동읍면)별": "지역"})
df["지역"] = df["지역"].fillna(method="ffill")
  • 일부 구역에만 시/군/구가 써 있고, 나머지는 NaN이므로 ffill()로 채워 넣는다.

 

[필요한 컬럼만 선택해서 정리]

df = df[df["항목"].isin(["총인구수 (명)", "20~39세 여성인구 (명)", "65세 이상 인구 (명)"])]
df = df.pivot_table(index="지역", columns="항목", values="2022년")
df.head()
  • pivot_table을 이용해 '지역'을 기준으로 항목을 나열

 

 

▶ 2. 소멸위험지수

소멸위험지수는 (20~39세 여성 인구수 / 65세 이상 고령 인구수)를 말한다.

이 값이 0.5보다 작으면 해당 지역은 장기적으로 인구 유지가 어렵다고 본다.

 

[소멸위험지수 계산 코드]

df["소멸위험지수"] = df["20~39세 여성인구 (명)"] / df["65세 이상 인구 (명)"]
df["소멸위기지역"] = df["소멸위험지수"] < 0.5
df.head()
  • 새로운 컬럼 두 개 생성
  • True인 지역이 실제 소멸위기 지역

 

 

[인구수 적은 군 지역]

인구수가 적은 군 지역에서 많이 나타난다.

df[df["소멸위기지역"] == True].sort_values("소멸위험지수").head(10)
  • 강원도, 경북, 전북 등 고령화가 심각한 군 단위 지역이 상위에 랭크

 

 

▶ 3. 지도 시각화

  • Python에서 지도 위에 데이터를 표현하려면 경계 정보(GeoJSON)가 필요함
  • 대표적인 도구는 folium
  • 그런데 folium은 지역 이름만 가지고 지도에 표현할 수 없음
    • 지역 ID가 필요함

 

[지도 데이터를 위한 ID 생성]

 

GeoJSON에서 사용하는 지역 ID는 일반적인 지역명과 다다.

예시는 다음과 같다.

  • 서울 강남구 → 강남구로 나오지 않고 서울 강남
  • 포항시 북구 → 포항 북구

따라서 행정구역 이름을 재가공해서 folium에서 쓸 수 있는 형태로 만들어야 한다.

 

def split_region_name(region):
    temp = region.split()
    if temp[1][-1] == "구":
        return temp[0] + " " + temp[1]
    else:
        return temp[0] + " " + temp[1][:-1]

지역 이름을 시 + 구 형태로 바꿔준다.

split_region_name("서울특별시 강남구") → "서울 강남"

 

 

▶ 4. Python에서 행정구역 지도를 시각화

folium을 사용해 지도 위에 데이터를 입히려면, 두 가지가 반드시 필요하다.

  1. 행정구역 경계 정보 → GeoJSON 파일
  2. 각 지역별 고유 ID → 이 ID와 DataFrame의 인구 데이터가 매칭되어야 함

 

*GeoJSON 이란?

  • 지도 데이터를 JSON 포맷으로 저장한 것
  • 시/군/구의 경계선 좌표가 담겨 있음
  • 하지만 한국의 행정구역명은 불규칙적이어서 ID 정규화가 필수

 

 

[GeoJSON 파일 불러오는 코드]

import json

geo_path = "skorea_municipalities_geo_simple.json"

with open(geo_path, encoding="utf-8") as f:
    geo_data = json.load(f)
  • 이 파일은 southkorea-maps GitHub에서 제공
  • 내부에는 200여 개의 시/군/구 경계가 담겨 있음

 

 

▶ 5. GeoJSON 내부에서 지역 ID 추출

지역마다 "properties": { "name": "서울 강남" } 형태의 이름이 있음

이 이름과 우리가 만든 split_region_name() 값이 정확히 일치해야 함

 

[인구 소멸 데이터와 GeoJSON ID 일치시키는 코드]

df["id"] = df.index.map(split_region_name)
df = df.reset_index()
df.head()
  • 이렇게 하면 지역명, 20~39세 여성 인구, 65세 이상 인구, 소멸위험지수, 소멸위기지역, id 컬럼이 모두 정리된다.

 

 

▶ 6. folium을 이용한 지도 시각화

  • folium.Choropleth
    • 경계 정보(GeoJSON)와 데이터를 연결해 색상 기반 표현 가능
    • fill_color, threshold_scale 등을 이용해 색상 범위 조절 가능

 

[소멸위험지수를 folium으로 지도에 표시하는 코드]

import folium

m = folium.Map(location=[36, 127], zoom_start=7)

folium.Choropleth(
    geo_data=geo_data,
    data=df,
    columns=["id", "소멸위험지수"],
    key_on="feature.properties.name",
    fill_color="YlOrRd",
    fill_opacity=0.7,
    line_opacity=0.2,
    legend_name="소멸위험지수 (<0.5 = 위험)"
).add_to(m)

m.save("소멸위험지도.html")
  • columns : ID와 지표 컬럼 지정
  • key_on : GeoJSON의 속성 경로
  • fill_color : 색상 맵 (Red = 위험, Yellow = 안전)
  • .save()로 결과 저장 가능

코드 실행하면 서울, 경기, 전남, 경북 등의 일부 군 단위 지역이 붉게 표시된다.

 

 

 

▶ 7. 카르토그램이란?

카르토그램은 지도에서 각 구역의 면적을 실제 값(인구 등)에 비례하도록 왜곡하는 지도

예시는 다음과 같다.

  • 선거 결과 지도 : 서울이 작아 보이지만 인구는 많음
  • 인구 기반 카르토그램 : 서울이 크게 부풀어져 표현됨

 

 

[카르토그램을 위한 좌표 + 값 데이터 준비 코드]

엑셀로 미리 준비된 지역 좌표(x, y) 데이터를 불러온다.

pop = pd.read_excel("07. population.xlsx")
pop = pop.set_index("지역")
pop["소멸위험지수"] = df.set_index("지역")["소멸위험지수"]
pop = pop.reset_index()
pop.head()

 

[plt로 카르토그램 그리는 코드]

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(10, 8))
for idx, row in pop.iterrows():
    plt.text(row["x"], row["y"], row["지역"], 
             fontsize=10, 
             color=plt.cm.Reds(row["소멸위험지수"]),
             ha='center')
plt.axis("off")
plt.title("대한민국 소멸위험지수 카르토그램")
plt.show()
  • plt.text() : 각 위치에 지역명을 표시
  • plt.cm.Reds() : 위험할수록 진한 색
  • ha='center' : 가운데 정렬

 

 

 

 

[나의 생각 정리]

주제도 재미있었고 카르토그램을 사용하는 것도 한눈에  들어와서 시각화하는데 좋은 것 같다.

일반 지도(folium)과 카르토그램(matplotlib)의 차이점을 인지해서 사용하면 좋을 것 같다.

 

 

[적용점]

여러 데이터 분석 시각화 할 때 사용

 

 

“이 글은 제로베이스 데이터 스쿨 주 3일반 강의 자료 일부를 발췌하여 작성되었습니다.”