1. 이제 '~시 ~구' 등의 형식으로 지역마다 고유한 ID를 붙여 줘야 한다. 먼저 '시도'컬럼의 고유한 값이 어떻게 되는지 확인해보자.
pop['시도'].unique()

2. 이렇게 많은 데이터에 전부 ID를 부여하자니, 시간도 오래 걸리고, 실수할 가능성도 높을 것이다.(물론 초보자인 나에게는 일일이 하나씩 부여해주는 게 시간이 더 절약될 수도 있긴 하지만) 일반적으로 모든 지역은 '~시' '~구' 이런 식으로, 시 다음 행정구로 구분된다. 따라서 아이디는 아래와 같은 형식으로 만들면 좋을 것이다.
- 서울 중구
- 서울 서초
- 통영
- 남양주
- 포항 북구
- 인천 남동
- 안양 만안
- 안양 동안
- 안산 단원
3. 대한민국의 구 목록은 위키피디아에 나와 있다. 한번 보자.
대한민국의 구 목록 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 다음 표는 대한민국의 구(자치구, 일반구)를 구 설치 순으로 배열한 것이다. 면적은 2011년 1월 1일 기준, 인구는 2011년 7월 주민등록인구통계 기준. 설치일 : 최
ko.wikipedia.org

4. 제로베이스 데이터스쿨 강사님은 직접 타이핑하여 tmp_gu라는 dic객체를 만드셨다. 그러나 한번 작성자는 이전에 배웠던 beautiful Soup을 이용하여 만들어보려고 한다. 어차피 html페이지 하나니까!
https://bookdaniel.tistory.com/85
미니프로젝트 02-01-02. 위키백과 문서 정보 가져오기, 시카고 맛집 메인페이지 분석
1. 이번에는 위키백과의 문서를 가져와보자. 작성자가 좋아하는 보더콜리에 대한 정보를 가져와볼 것이다. https://ko.wikipedia.org/wiki/%EB%B3%B4%EB%8D%94_%EC%BD%9C%EB%A6%AC\ 보더 콜리 - 위키백과, 우리 모두
bookdaniel.tistory.com
from bs4 import BeautifulSoup
import urllib
from urllib.request import Request, urlopen
# soup로 html 받아오기
html = 'https://ko.wikipedia.org/wiki/{search_words}'
req = Request(html.format(search_words = urllib.parse.quote('대한민국의_구_목록')))
response = urlopen(req)
soup = BeautifulSoup(response, 'html.parser')
gu_list = []
temp = soup.find_all('td')
for item in temp:
gu_list.append(item.get_text())
tmp = []
dic = {}
# 딕셔너리 객체 value에 빈 배열 넣어 주기
for n in range(0, len(gu_list)-25, 7):
if '→' in gu_list[25+n]:
tmp_str = gu_list[25+n].split()
dic[tmp_str[3]] = []
else:
tmp_str = gu_list[25+n].split()
dic[tmp_str[0]] = []
# 딕셔너리 객체 value에 값 넣어주기
for n in range(0, len(gu_list)-25, 7):
if '→' in gu_list[25+n]:
tmp_str = gu_list[25+n].split()
dic.get(tmp_str[3]).append(tmp_str[4])
else:
tmp_str = gu_list[25+n].split()
dic.get(tmp_str[0]).append(tmp_str[1])
# 현재 폐지된 구를 제거
dic.get('부천').remove('원미구')
dic.get('부천').remove('소사구')
dic.get('부천').remove('오정구')
dic.get('울산').remove('울주구')
dic.get('마산').remove('합포구')
dic.get('마산').remove('회원구')
del dic['마산']
위같이 코드를 짰다. 결과는 다음과 같다.
# {'서울': ['종로구', '동대문구', '성동구', '서대문구', '용산구', '영등포구', '마포구', '성북구', '도봉구', '관악구', '강남구', '강서구', '은평구', '강동구',
# '구로구', '동작구','송파구','중랑구', '노원구','서초구','양천구','광진구','강북구','금천구'],
# '부산': ['중구', '서구','영도구','동구','부산진구','동래구','남구','북구','해운대구','사하구','금정구','강서구','연제구','수영구','사상구'],
# '대구': ['중구', '동구', '서구', '남구', '북구', '수성구', '달서구'],
# '인천': ['중구', '동구', '미추홀구', '부평구', '서구', '남동구', '연수구', '계양구'],
# '광주': ['동구', '서구', '북구', '광산구', '남구'],
# '대전': ['동구', '중구', '서구', '유성구', '대덕구'],
# '울산': ['중구', '남구', '동구', '북구'],
# '부천': ['원미구', '소사구', '오정구'],
# '수원': ['권선구', '장안구', '팔달구', '영통구'],
# '성남': ['수정구', '중원구', '분당구'],
# '전주': ['덕진구', '완산구'],
# '안양': ['만안구', '동안구'],
# '청주': ['상당구', '흥덕구', '청원구', '서원구'],
# '포항': ['북구', '남구'],
# '고양': ['덕양구', '일산동구', '일산서구'],
# '안산': ['상록구', '단원구'],
# '용인': ['처인구', '기흥구', '수지구'],
# '천안': ['동남구', '서북구'],
# '창원': ['의창구', '성산구', '마산합포구', '마산회원구', '진해구']}
이제 dic.get()명령어로 시와 그에 따르는 구들을 리스트로 받아볼 수 있다.
5. 우리는 '광역시도' 컬럼과 '시도' 컬럼을 조합하여 고유한 ID를 만들어줄 것이다. '광역시도'의 unique()를 보면 크게 도와 광역시로 나뉘는 것을 알 수 있다. 도 안에 속한 시들은 굳이 앞에 강원 ~~, 경기 ~~로 도를 붙여줄 필요 없이 그냥 시 이름만 ID로 지정해줘도 된다. 그러나 광역시 안에 속한 구들은 앞에 '서울 마포구', '수원 팔달구'처럼 시를 언급해주는 게 좋다.


6. 일반 시의 이름과 세종시, 그리고 광역시도의 일반 구를 정리한다.
si_name = [None] * len(pop)
for idx, row in pop.iterrows():
if row['광역시도'][-3:] not in ['광역시', '특별시', '자치시' ]:
si_name[idx] = row['시도'][:-1]
elif row['광역시도'] == '세종특별자치시':
si_name[idx] = '세종'
else:
if len(row['시도']) == 2:
si_name[idx] = row['광역시도'][:2] + " " + row['시도']
else:
si_name[idx] = row['광역시도'][:2] + " " + row['시도'][:-1]

7. 플러스로 행정구에 대해 특별히 다시 계산해줘야 한다. 4번에서 만든 시/구 사전형데이터를 참고하여 계산해준다. 특별시나 고성의 경우 경남, 강원에 동일한 지명이 있으므로 구분해준다. 최종 코드는 다음과 같다.
si_name = [None] * len(pop)
for idx, row in pop.iterrows():
if row['광역시도'][-3:] not in ['광역시', '특별시', '자치시' ]:
si_name[idx] = row['시도'][:-1]
elif row['광역시도'] == '세종특별자치시':
si_name[idx] = '세종'
else:
if len(row['시도']) == 2:
si_name[idx] = row['광역시도'][:2] + " " + row['시도']
else:
si_name[idx] = row['광역시도'][:2] + " " + row['시도'][:-1]
temp_gu_dict = dic
# 행정구에 대해 특별히 다시 계산
for idx, row in pop.iterrows():
if row['광역시도'][-3:] not in ['광역시', '특별시', '자치시']:
for keys, values in temp_gu_dict.items():
if row['시도'] in values:
if len(row['시도']) == 2:
si_name[idx] = keys + " " + row['시도']
elif row['시도'] in ['마산합포구', '마산회원구']:
si_name[idx] = keys + " " + row['시도'][2:-1]
else:
si_name[idx] = keys + " " + row['시도'][:2]
# 특별히 고성군에 대해 한 번 더 신경써준다
for idx, row in pop.iterrows():
if row['광역시도'][-3:] not in ['광역시', '특별시', '자치시']:
if row['시도'][:-1] == '고성' and row['광역시도'] == '강원도':
si_name[idx] = '고성(강원)'
elif row['시도'][:-1] == '고성' and row['광역시도'] == '경상남도':
si_name[idx] = '고성(경남)'

8. 이제 새로 만든 si_name 리스트를 데이터프레임에 합쳐 준다.

이상 위키피디아에서 한국 구 데이터를 Beautiful Soup으로 불러와 데이터프레임의 광역시도/시도의 데이터와 대조하여 적절히 가공하고 데이터프레임에 합치는 것까지 완료했다. 이제 이 데이터를 바탕으로 시각화를 해보자.
'데이터분석 > 미니프로젝트 06. 인구 분석' 카테고리의 다른 글
| 06-03-02. 카르토그램으로 인구현황 시각화하기(2) (0) | 2024.04.27 |
|---|---|
| 06-03-01. 카르토그램으로 인구현황 시각화하기(01) (1) | 2024.04.23 |
| 06-01. 인구소멸위기지역 파악하기 프로젝트 개요, 데이터 수집 및 정리 (2) | 2024.04.21 |