상세 컨텐츠

본문 제목

[빅데이터 분석] 09. 지리 정보 분석 II

[SW]/빅데이터 (2023) (완)

by 시원00 2023. 7. 25. 14:18

본문

728x90

지리 정보 분석 II

 

project9. 행정 구역별 의료기관 현황 분석하기

  1. 핵심 개념: 블록맵
  2. 데이터 수집
    • 공공보건의료기관현황.csv
    • 행정 구역 주소 체계 데이터: 국가통계포털
  3. 데이터 준비 및 탐색
    • 행정 구역 이름으로 주소 수정
    • 행정 구역별 공공 보건 의료 기관 수 집계
    • 행정 구역별 인구수 데이터 정리
    • 테이블에 필요한 컬럼 추출 후 테이블 병합
  4. 시각화
    • 행정 구역별 공공 보건 의료 기관 수에 대한 바 차트 그리기
    • 행정 구역별 인구수 대비 공공 보건 의료 기관 비율에 대한 바 차트 그리기
    • 공공 보건 의료 기관 지도에 표시하기

 

 

1. 핵심 개념 이해: 블록맵

 

 

2. 데이터 수집

 

공공데이터 포털

- www.data.go.kr

- '공공보건 의료기간 현황' 검색

 

 

3. 데이터 준비 및 탐색

 

공공보건 의료기관 현황 데이터 준비하기

(1) 데이터 파일 확인

import pandas as pd
import numpy as np

data = pd.read_csv('공공보건의료기관현황.csv', index_col=0, encoding='cp949', engine='python')
data.head()

Out:

 

(2) 주소 정리하기

- 데이터 프레임을 어떤 함수에 따라서 전체 또는 특정 열의 값들을 일괄적으로 변경하기 원할 때 사용

- 사용법: 데이터 프레임['열 이름'].apply(함수명)

addr=pd.DataFrame(data['주소'].apply(lambda v:v.split()[0:2]).tolist(), columns=('시도','구군'))
addr.head()

Out:

 

(3) 주소 체계에 맞지 않게 표현된 내용 찾아서 수정

- '시도' 열 수정: '시'가 아닌 데이터 찾아서 수정

- '창원시 -> 경상남도 창원시', '경산시 -> 경상북도 경산시', '천안시 -> 충청남도 천안시'로 변경

addr['시도'].unique()

Out:

array(['강원도', '경기도', '경기', '경남', '창원시', '경상남도', '경상북도', '경산시', '경북',
       '인천광역시', '대구광역시', '전라남도', '대전광역시', '광주광역시', '제주특별자치도', '부산광역시',
       '전라북도', '충북', '서울특별시', '서울시', '부산특별시', '대전시', '충남', '전남', '충청남도',
       '울산광역시', '전북', '천안시', '충청북도'], dtype=object)

addr[addr['시도']=='창원시']

Out:

addr.iloc[27] = ['경상남도', '창원시']
addr.iloc[31] = ['경상남도', '창원시']
addr['시도'].unique()

Out:

array(['강원도', '경기도', '경기', '경남', '경상남도', '경상북도', '경산시', '경북', '인천광역시',
       '대구광역시', '전라남도', '대전광역시', '광주광역시', '제주특별자치도', '부산광역시', '전라북도',
       '충북', '서울특별시', '서울시', '부산특별시', '대전시', '충남', '전남', '충청남도', '울산광역시',
       '전북', '천안시', '충청북도'], dtype=object)

addr[addr['시도']=='경산시']

Out:

addr.iloc[47] = ['경상북도', '경산시']
addr[addr['시도']=='천안시']

Out:

addr.iloc[209] = ['충청남도', '천안시']
addr.iloc[210] = ['충청남도', '천안시']
addr['시도'].unique()

Out:

array(['강원도', '경기도', '경기', '경남', '경상남도', '경상북도', '경북', '인천광역시', '대구광역시',
       '전라남도', '대전광역시', '광주광역시', '제주특별자치도', '부산광역시', '전라북도', '충북',
       '서울특별시', '서울시', '부산특별시', '대전시', '충남', '전남', '충청남도', '울산광역시', '전북',
       '충청북도'], dtype=object)

addr_aliases = {'경기':'경기도', '경남':'경상남도', '경북':'경상북도', 
               '충북':'충청북도', '서울시':'서울특별시', '부산특별시':'부산광역시',
               '대전시':'대전광역시', '충남':'충청남도', '전남':'전라남도', '전북':'전라북도'} #딕셔너리
addr['시도'] = addr['시도'].apply(lambda s: addr_aliases.get(s, s))
#get 함수: 해당 key 값에 대응하는 value 리턴
#사용법: 딕셔너리.get(key, 디폴트값)

addr['시도'].unique() #수정 확인

Out:

array(['강원도', '경기도', '경상남도', '경상북도', '인천광역시', '대구광역시', '전라남도', '대전광역시',
       '광주광역시', '제주특별자치도', '부산광역시', '전라북도', '충청북도', '서울특별시', '충청남도',
       '울산광역시'], dtype=object)

 

- '구군' 열 수정

addr['구군'].unique()

Out:

array(['춘천시', '삼척시', '영월군', '원주시', '강릉시', '속초시', '정선군', '수원시', '이천시',
       '안성시', '의정부시', '포천시', '파주시', '용인시', '평택시', '시흥시', '여주시', '남양주시',
       '동두천시', '안산시', '부천시', '통영시', '사천시', '창원시', '김해시', '양산시', '거창군',
       '남해군', '의령군', '포항시', '김천시', '안동시', '울진군', '경주시', '구미시', '영주시',
       '상주시', '문경시', '경산시', '의성군', '청도군', '고령군', '칠곡군', '봉화군', '울릉군',
       '부평구', '북구', '순천시', '대덕구', '태백시', '동해시', '화성시', '광산구', '남구', '중구',
       '아란13길', '서구', '전주시', '진주시', '청주시', '종로구', '성남시', '동구', '화순군',
       '강동구', '사상구', '달서구', '해운대구', '유성구', '가평군', '양주시', '고양시', '홍천군',
       '양구군', '청원군', '계룡시', '논산시', '함평군', '양평군', '수성구', '달성군', '연수구',
       '노원구', '기장군', '공주시', '강북구', '광진구', '나주시', '창녕군', '목포시', '고흥군',
       '연제구', '동매로', '서초구', '은평구', '중랑구', '강남구', '동작구', '동대문구', '양천구',
       '성동구', '송파구', '울주군', '계양구', '옹진군', '보성군', '광양시', '영광군', '무안군',
       '진도군', '강진군', '곡성군', '여수시', '신안군', '장성군', '완주군', '부안군', '정읍시',
       '남원시', '군산시', '고창군', '진안군', '제주시', '서귀포시', '천안시', '보령시', '서산시',
       '서천군', '홍성군', '제천시', '충주시', '영동군', '단양군'], dtype=object)

addr[addr['구군']=='아란13길']
addr.iloc[75]=['제주특별자치도','제주시']
addr['구군'].unique()

Out:

array(['춘천시', '삼척시', '영월군', '원주시', '강릉시', '속초시', '정선군', '수원시', '이천시',
       '안성시', '의정부시', '포천시', '파주시', '용인시', '평택시', '시흥시', '여주시', '남양주시',
       '동두천시', '안산시', '부천시', '통영시', '사천시', '창원시', '김해시', '양산시', '거창군',
       '남해군', '의령군', '포항시', '김천시', '안동시', '울진군', '경주시', '구미시', '영주시',
       '상주시', '문경시', '경산시', '의성군', '청도군', '고령군', '칠곡군', '봉화군', '울릉군',
       '부평구', '북구', '순천시', '대덕구', '태백시', '동해시', '화성시', '광산구', '남구', '중구',
       '제주시', '서구', '전주시', '진주시', '청주시', '종로구', '성남시', '동구', '화순군', '강동구',
       '사상구', '달서구', '해운대구', '유성구', '가평군', '양주시', '고양시', '홍천군', '양구군',
       '청원군', '계룡시', '논산시', '함평군', '양평군', '수성구', '달성군', '연수구', '노원구',
       '기장군', '공주시', '강북구', '광진구', '나주시', '창녕군', '목포시', '고흥군', '연제구',
       '동매로', '서초구', '은평구', '중랑구', '강남구', '동작구', '동대문구', '양천구', '성동구',
       '송파구', '울주군', '계양구', '옹진군', '보성군', '광양시', '영광군', '무안군', '진도군',
       '강진군', '곡성군', '여수시', '신안군', '장성군', '완주군', '부안군', '정읍시', '남원시',
       '군산시', '고창군', '진안군', '서귀포시', '천안시', '보령시', '서산시', '서천군', '홍성군',
       '제천시', '충주시', '영동군', '단양군'], dtype=object)

 

(4) 행정구역별 공공보건의료기관의 수 구하기

addr['시도구군'] = addr.apply(lambda r:r['시도']+' '+r['구군'], axis=1) #컬럼 합치기
addr.head() #열 추가 확인

Out:

addr['count'] = 0
addr_group = addr.groupby(['시도','구군','시도구군'], as_index=False).count()
addr_group.head() #결과확인

Out:

addr_group = addr_group.set_index('시도구군') #index를 '시도구군'으로 변경
addr_group.head()

Out:

 

행정 구역별 인구수 데이터 준비하기

(1) 데이터 정리하기

#행정구역별 인구수 데이터 준비하기
population = pd.read_excel('행정구역_시군구_별_성별_인구수.xlsx')
population.head()

Out:

population = population.rename(columns={'행정구역(시도)별':'시도',
                                       '행정구역(군구)별':'구군'})
#데이터 병합을 위해 컬럼 이름 동일하게 재작성
population.head()

Out:

for element in range(0, len(population)):
    population['시도'][element]=population['시도'][element].strip()
    population['구군'][element]=population['구군'][element].strip()
    #시도, 군구 열 
population['시도구군']=population.apply(lambda r:r['시도']+' '+r['구군'],axis=1)
population=population[population.구군 != '소계']
population=population.set_index('시도구군')
population.head()

Out:

 

(2) addr_group과 population 병합

addr_population_merge = pd.merge(addr_group, population, left_index=True, right_index=True)
addr_population_merge.head() #병합 결과 확인

Out:

local_population = addr_population_merge[['시도_x', '구군_x', 'count', '총인구수 (명)']]
local_population.head() #필요한 컬럼만 추출 확인

Out:

local_population = local_population.rename(columns = {'시도_x':'시도', '구군_x':'구군', '총인구수 (명)':'인구수'})
count = local_population['count'] #컬럼 이름 변경
local_population['ratio'] = count.div(local_population['인구수'], axis = 0)*10000
#인구수 대비 공공보건의료기관 비율 구하기

local_population.head()

Out:

 

 

4. 분석 모델 구축 및 시각화

 

행정구역별 공공보건의료기관 수에 대한 바 차트 그리기

from matplotlib import pyplot as plt
from matplotlib import rcParams, style
style.use('ggplot')
from matplotlib import font_manager, rc
plt.rcParams['font.family'] = 'AppleGothic'
MC_count = local_population[['count']]
MC_count = MC_count.sort_values('count', ascending=False)
plt.rcParams['figure.figsize']=(25,5)
MC_count.plot(kind='bar', rot=90)
plt.show()

Out:

 

행정구역별 인구수 대비 공공보건의료기관 비율에 대한 바 차트 그리기

MC_ratio = local_population[['ratio']]
MC_ratio = MC_ratio.sort_values('ratio', ascending = False)
plt.rcParams['figure.figsize']=(25,5)
MC_ratio.plot(kind='bar', rot=90)
plt.show()


Out:

 

 


(추가) project 9-1. 공공의료기관 지도 표시 및 팝업

 

전체 코드

import pandas as pd
cbData = pd.read_csv('공공보건의료기관현황.csv', encoding='CP949', index_col=0, engine='python')

addr = []
for address in cbData.주소:
    addr.append(str(address).split())
addr

Out:

addr2 = []
for i in range(len(addr)):
    if addr[i][0] == "경기": addr[i][0] = "경기도"
    elif addr[i][0] == "경남": addr[i][0] = "경상남도"
    elif addr[i][0] == "창원시": addr[i][0] = "경상남도 창원시"
    elif addr[i][0] == "경산시": addr[i][0] = "경산북도 경산시"
    elif addr[i][0] == "경북": addr[i][0] = "경상북도"
    elif addr[i][0] == "충북": addr[i][0] = "충청북도"
    elif addr[i][0] == "서울시": addr[i][0] = "서울광역시"
    elif addr[i][0] == "대전시": addr[i][0] = "대전광역시"
    elif addr[i][0] == "충남": addr[i][0] = "층청남도"
    elif addr[i][0] == "전남": addr[i][0] = "전라남도"
    elif addr[i][0] == "천안시": addr[i][0] = "충청남도 천안시"
    elif addr[i][0] == "전북": addr[i][0] = "전라북도"
    addr2.append(''.join(addr[i]))
addr2

Out:

addr2 = pd.DataFrame(addr2, columns=['address2'])
cbData2 = pd.concat([cbData, addr2], axis=1)
cbData2.head()

cbData2.to_csv('공공보건의료기관현황2.csv', encoding='cp949', index=False)

- 저장된 csv 파일('공공보건의료현황2.csv')을 이용해서 geocoder(http://www.gisdeveloper.co.kr/?cat=143)를 통해 위도, 경도 포함한 파일 생성('공공보건의료현황3.csv')

import folium
cbGeoData = pd.read_csv('공공보건의료기관현황3.csv', encoding='UTF-8', engine='python')
mapCB = folium.Map(location=[37.5555038, 126.9737511], zoom_start=15)
for i, store in cbGeoData.iterrows():
    folium.Marker(location=[store['_Y'],store['_X']],
                 popup=store['field1'], icon=folium.Icon(color='red', icon='star')).add_to(mapCB)
mapCB.save('공공의료기관_map_cb.html')

 

결과

공공의료기관_map_cb.html

 

 

FIN.

728x90

관련글 더보기

댓글 영역