[COMPAS 광양시] 주어진 데이터를 활용하여 행정동별 정보를 모아보자! ( 충전소, 인구 수, 전기차 보급현황 )

솜씨좋은장씨

·

2020. 10. 1. 12:36

데이터 분석 활용 시간

2020년 10월 01일 12시 30분 ~ 13시 30분 ( 총 1시간 소요 )

 

사용 데이터

01.광양시_충전기설치현황.csv

03.광양시_자동차등록현황_격자(100X100).geojson

06.광양시_전기차보급현황(연도별,읍면동별).csv

07.광양시_법정동별_인구현황(읍면동리).csv

20.광양시_행정경계(읍면동).geojson

 

활용 코드 및 내용

 

[COMPAS 광양시] 100 x 100 격자 데이터 활용 각 읍면동별 차량 등록 정보 데이터 만들기

데이터 분석 활용시간 2020년 9월 26일 07시 30분 ~ 09시 30분 ( 2시간 ) 사용 데이터 03.광양시_자동차등록현황_격자(100X100).geojson 19.광양시_법정경계(읍면동).geojson 활용 코드 및 내용 필요 라이브러리.

ideans.tistory.com

지난 게시물에서 100x100 격자 데이터 활용하여 만든 데이터는 법정경계를 기준으로 데이터를 묶어 활용했습니다.

다른 데이터를 확인해보니 대체로 데이터가 행정경계를 기준으로 구축되어있어 행정경계로 다시 묶어보았습니다.

 

필요 라이브러리 import

import os
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point, Polygon
from tqdm import tqdm

 

데이터 목록 Python으로 가져오기

file_list = os.listdir("./data/")
file_list = sorted(file_list)
file_list
['01.광양시_충전기설치현황.csv',
 '02.광양시_주차장_공간정보.csv',
 '03.광양시_자동차등록현황_격자(100X100).geojson',
 '04.광양시_대중집합시설_생활체육시설.csv',
 '05.광양시_대중집합시설_야영장.csv',
 '06.광양시_전기차보급현황(연도별,읍면동별).csv',
 '07.광양시_법정동별_인구현황(읍면동리).csv',
 '08.광양시_격자별인구현황(100X100).geojson',
 '09.광양시_버스정류장 및 택시승차장_공간정보.csv',
 '14.광양시_소유지정보.geojson',
 '15.광양시_건물정보.geojson',
 '16.광양시_도로정보.geojson',
 '17.광양시_건물분포도(연면적)_격자(100X100).geojson',
 '18.광양시_법정경계(시군구).geojson',
 '19.광양시_법정경계(읍면동).geojson',
 '20.광양시_행정경계(읍면동).geojson',
 '21.광양시_법정경계(리).geojson',
 '22.광양시_연속지적.geojson',
 '23.광양시_개발행위제한구역.geojson',
 '24.광양시_도시계획(공간시설).geojson',
 '25.광양시_도시계획(공공문화체육시설).geojson',
 '26.광양시_도시계획(교통시설).geojson',
 '27.광양시_도시계획(유통공급시설).geojson',
 '28.광양시_도시계획(환경기초시설).geojson',
 '29.광양시_산업단지(단지경계).geojson',
 '30.광양시_산업단지(시설용지도면).geojson',
 '31.광양시_산업단지(단지용도지역).geojson',
 '32.광양시_DEM.img',
 '33.광양시_고도_격자(100X100).geojson',
 '34.코드정의서.xlsx',
 'extra']

행정경계 기준 읍면동 정보 가져오기

emd_gdf = gpd.read_file("./data/" + file_list[15])
emd_gdf

자동차 등록정보 가져오기

car_gdf = gpd.read_file("./data/" + file_list[2])
car_gdf.head()

행정경계 기준 구역 Multipolygon -> Polygon 바꾸어주기

umd_polys = {}

multi_polys = list(emd_gdf['geometry'])

for i in tqdm(range(len(multi_polys))):
    polys = []
    if multi_polys[i].geom_type == "MultiPolygon":
        for poly in multi_polys[i]:
            polys.append(poly)
    umd_polys[emd_gdf['ADM_DR_NM'].iloc[i]] = polys
umd_polys
{'봉강면': [<shapely.geometry.polygon.Polygon at 0x7fafe9602b38>],
 '옥룡면': [<shapely.geometry.polygon.Polygon at 0x7fafe96027f0>],
 '옥곡면': [<shapely.geometry.polygon.Polygon at 0x7fafe9602748>],
 '진상면': [<shapely.geometry.polygon.Polygon at 0x7fafe9602d68>],
 '진월면': [<shapely.geometry.polygon.Polygon at 0x7fafe9602780>],
 '다압면': [<shapely.geometry.polygon.Polygon at 0x7fafe96028d0>],
 '골약동': [<shapely.geometry.polygon.Polygon at 0x7fafe9602dd8>,
  <shapely.geometry.polygon.Polygon at 0x7fafe9602d30>],
 '중마동': [<shapely.geometry.polygon.Polygon at 0x7fafe9606e10>],
 '광영동': [<shapely.geometry.polygon.Polygon at 0x7fafe9606c18>],
 '태인동': [<shapely.geometry.polygon.Polygon at 0x7fafe9606a20>,
  <shapely.geometry.polygon.Polygon at 0x7fafe9606a90>],
 '금호동': [<shapely.geometry.polygon.Polygon at 0x7fafe9606898>,
  <shapely.geometry.polygon.Polygon at 0x7fafe9606630>],
 '광양읍': [<shapely.geometry.polygon.Polygon at 0x7fafe9606438>,
  <shapely.geometry.polygon.Polygon at 0x7fafe96064a8>]}

Polygon을 활용하여 각 행정경계 별 자동차 등록 현황 만들기

umd_dict = {"봉강면": [], "옥룡면": [], "옥곡면": [], "진상면": [], "진월면": [], "다압면": [], "골약동": [], "중마동": [], 
        "광영동": [], "태인동": [], "금호동": [], "광양읍": []}

umd_key  = list(umd_polys.keys())

for c in tqdm(range(len(list(car_gdf['geometry'])))):
    for i, key in enumerate(umd_key):
        umd_poly = umd_polys[key]
        
        for poly in umd_poly:
            if poly.contains(car_gdf['geometry'].iloc[c]):
                umd_dict[emd_gdf['ADM_DR_NM'].iloc[i]].append(car_gdf['id'].iloc[c])
umd_car_infos = {}

keys = list(umd_dict.keys())

for key in keys:
    umd_ids = umd_dict[key]

    total = 0

    for i in tqdm(range(len(umd_ids))):
        temp_gdf = car_gdf[car_gdf['id'] == umd_ids[i]]

        total = total + temp_gdf['totale'].iloc[0]

    umd_car_infos[key] = total
umd_car_infos
{'봉강면': 209,
 '옥룡면': 285,
 '옥곡면': 382,
 '진상면': 271,
 '진월면': 296,
 '다압면': 173,
 '골약동': 282,
 '중마동': 5855,
 '광영동': 1212,
 '태인동': 453,
 '금호동': 1556,
 '광양읍': 4777}

충전기 설치현황 데이터 불러오기

charge_st_df = pd.read_csv("./data/" + file_list[0])
charge_st_df.head()

각 충전소 별 좌표 정보를 활용하여 Point 만들어주기

point_dict = {}

for i in range(len(charge_st_df)):
    point_dict[charge_st_df['충전소명'].iloc[i]] = {}
    
    point_dict[charge_st_df['충전소명'].iloc[i]]['Point'] = Point(charge_st_df['lon'].iloc[i], charge_st_df['lat'].iloc[i])

여기서 중요한 점은 위도, 경도 정보를 활용할때 Point( 경도, 위도 ) 순으로 넣어주어야 합니다.

point_dict
{'LF스퀘어 광양점': {'Point': <shapely.geometry.point.Point at 0x7fafe92be7b8>},
 '광양만권경제자유구역청': {'Point': <shapely.geometry.point.Point at 0x7fafe92be3c8>},
 '광양송보파인빌5차아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92be4a8>},
 '광양시 모리스모텔': {'Point': <shapely.geometry.point.Point at 0x7fafe92be080>},
 '광양시 백운쇼핑센타': {'Point': <shapely.geometry.point.Point at 0x7fafe92be048>},
 '광양시 블루핸즈(광양정비센터)': {'Point': <shapely.geometry.point.Point at 0x7fafe92be5c0>},
 '광양시 비치모텔': {'Point': <shapely.geometry.point.Point at 0x7fafe92be1d0>},
 '광양시 포스코 ICT 광양사업소': {'Point': <shapely.geometry.point.Point at 0x7fafe92be400>},
 '광양시 프라자모텔': {'Point': <shapely.geometry.point.Point at 0x7fafe92be0b8>},
 '광양시 광양읍사무소': {'Point': <shapely.geometry.point.Point at 0x7fafe92be630>},
 '광양시 광영동주민센터': {'Point': <shapely.geometry.point.Point at 0x7fafe92be240>},
 '광양시 옥곡면사무소': {'Point': <shapely.geometry.point.Point at 0x7fafe92be588>},
 '광양읍사무소 앞 주차장': {'Point': <shapely.geometry.point.Point at 0x7fafe92be198>},
 '광양주공이차아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92bea90>},
 '한국전력광양지사': {'Point': <shapely.geometry.point.Point at 0x7fafe92be6a0>},
 '광영 근린공원': {'Point': <shapely.geometry.point.Point at 0x7fafe92be9e8>},
 '광영동 가야아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92be5f8>},
 '구산칠성이편한세상': {'Point': <shapely.geometry.point.Point at 0x7fafe92bec18>},
 '대광로제비앙2차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92be828>},
 '대신증권앞 주차장': {'Point': <shapely.geometry.point.Point at 0x7fafe92beb70>},
 '마틴모텔': {'Point': <shapely.geometry.point.Point at 0x7fafe92be780>},
 '섬진강휴게소(부산방향)': {'Point': <shapely.geometry.point.Point at 0x7fafe92befd0>},
 '섬진강휴게소(순천방향)': {'Point': <shapely.geometry.point.Point at 0x7fafe92bec88>},
 '쉐보레동광양지점서비스': {'Point': <shapely.geometry.point.Point at 0x7fafe92bebe0>},
 '인동숲주차장': {'Point': <shapely.geometry.point.Point at 0x7fafe92bee10>},
 '중마버스터미널 공영주차장': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1eb8>},
 '중마상설시장 주차장': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1f28>},
 '호텔자바': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1d30>},
 '홈플러스 광양점': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1cc0>},
 '마동근린체육공원': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1b38>},
 '광양중마호반리젠시빌': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1ac8>},
 '태영1차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1940>},
 '태영2차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92c18d0>},
 '성호2-1차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92c16d8>},
 '송보파인빌 6차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe9052160>},
 '송보파인빌 7차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe9052358>},
 '남해오네뜨 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe9052320>},
 '광양읍 목성 주공아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe90520b8>}}

각 충전소 별 행정경계 기준 읍면동 확인하기

umds = []
point_dict_keys = list(point_dict.keys())
umd_keys = list(umd_polys.keys())

for key in point_dict_keys:
    for umd_key in umd_keys:
        umd_ploy_lists = umd_polys[umd_key]

        for umd_polygon in umd_ploy_lists.values():
            if umd_polygon.contains(point_dict[key]['Point']) == True:
                point_dict[key]['umd'] = umd_key
                umds.append(umd_key)
                break
    if 'umd' not in point_dict[key].keys():
        point_dict[key]['umd'] = "정보없음"
point_dict
{'LF스퀘어 광양점': {'Point': <shapely.geometry.point.Point at 0x7fafe92be7b8>,
  'umd': '광양읍'},
 '광양만권경제자유구역청': {'Point': <shapely.geometry.point.Point at 0x7fafe92be3c8>,
  'umd': '광양읍'},
 '광양송보파인빌5차아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92be4a8>,
  'umd': '중마동'},
 '광양시 모리스모텔': {'Point': <shapely.geometry.point.Point at 0x7fafe92be080>,
  'umd': '광영동'},
 '광양시 백운쇼핑센타': {'Point': <shapely.geometry.point.Point at 0x7fafe92be048>,
  'umd': '금호동'},
 '광양시 블루핸즈(광양정비센터)': {'Point': <shapely.geometry.point.Point at 0x7fafe92be5c0>,
  'umd': '광양읍'},
 '광양시 비치모텔': {'Point': <shapely.geometry.point.Point at 0x7fafe92be1d0>,
  'umd': '진월면'},
 '광양시 포스코 ICT 광양사업소': {'Point': <shapely.geometry.point.Point at 0x7fafe92be400>,
  'umd': '태인동'},
 '광양시 프라자모텔': {'Point': <shapely.geometry.point.Point at 0x7fafe92be0b8>,
  'umd': '광영동'},
 '광양시 광양읍사무소': {'Point': <shapely.geometry.point.Point at 0x7fafe92be630>,
  'umd': '광양읍'},
 '광양시 광영동주민센터': {'Point': <shapely.geometry.point.Point at 0x7fafe92be240>,
  'umd': '광영동'},
 '광양시 옥곡면사무소': {'Point': <shapely.geometry.point.Point at 0x7fafe92be588>,
  'umd': '옥곡면'},
 '광양읍사무소 앞 주차장': {'Point': <shapely.geometry.point.Point at 0x7fafe92be198>,
  'umd': '광양읍'},
 '광양주공이차아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92bea90>,
  'umd': '중마동'},
 '한국전력광양지사': {'Point': <shapely.geometry.point.Point at 0x7fafe92be6a0>,
  'umd': '중마동'},
 '광영 근린공원': {'Point': <shapely.geometry.point.Point at 0x7fafe92be9e8>,
  'umd': '광영동'},
 '광영동 가야아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92be5f8>,
  'umd': '광영동'},
 '구산칠성이편한세상': {'Point': <shapely.geometry.point.Point at 0x7fafe92bec18>,
  'umd': '광양읍'},
 '대광로제비앙2차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92be828>,
  'umd': '중마동'},
 '대신증권앞 주차장': {'Point': <shapely.geometry.point.Point at 0x7fafe92beb70>,
  'umd': '중마동'},
 '마틴모텔': {'Point': <shapely.geometry.point.Point at 0x7fafe92be780>,
  'umd': '광영동'},
 '섬진강휴게소(부산방향)': {'Point': <shapely.geometry.point.Point at 0x7fafe92befd0>,
  'umd': '진월면'},
 '섬진강휴게소(순천방향)': {'Point': <shapely.geometry.point.Point at 0x7fafe92bec88>,
  'umd': '진월면'},
 '쉐보레동광양지점서비스': {'Point': <shapely.geometry.point.Point at 0x7fafe92bebe0>,
  'umd': '태인동'},
 '인동숲주차장': {'Point': <shapely.geometry.point.Point at 0x7fafe92bee10>,
  'umd': '광양읍'},
 '중마버스터미널 공영주차장': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1eb8>,
  'umd': '중마동'},
 '중마상설시장 주차장': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1f28>,
  'umd': '중마동'},
 '호텔자바': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1d30>,
  'umd': '중마동'},
 '홈플러스 광양점': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1cc0>,
  'umd': '중마동'},
 '마동근린체육공원': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1b38>,
  'umd': '중마동'},
 '광양중마호반리젠시빌': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1ac8>,
  'umd': '중마동'},
 '태영1차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92c1940>,
  'umd': '중마동'},
 '태영2차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92c18d0>,
  'umd': '중마동'},
 '성호2-1차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe92c16d8>,
  'umd': '중마동'},
 '송보파인빌 6차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe9052160>,
  'umd': '중마동'},
 '송보파인빌 7차 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe9052358>,
  'umd': '광양읍'},
 '남해오네뜨 아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe9052320>,
  'umd': '광양읍'},
 '광양읍 목성 주공아파트': {'Point': <shapely.geometry.point.Point at 0x7fafe90520b8>,
  'umd': '광양읍'}}

만든 데이터를 바탕으로 충전소 데이터 정보에 추가하기

st_names = list(charge_st_df['Address'])
umd_infos = []

for st_name in tqdm(st_names):
    try:
        umd_name = point_dict[st_name]['umd']
        umd_infos.append(umd_name)
    except Exception as E:
        umd_name = None
        print(st_name)
        print(f"Error Message : {E}")
        umd_infos.append(umd_name)
charge_st_df['읍면동 (행정경계)'] = umd_infos

charge_st_df.head()
charge_st_umd_list = list(charge_st_df['읍면동 (행정경계)'])

car_enroll_infos = []

for umd in charge_st_umd_list:
    car_enroll_info = umd_car_infos[umd]
    
    car_enroll_infos.append(car_enroll_info)
    
charge_st_df['자동차 등록 현황 (행정경계)'] = car_enroll_infos
charge_st_df.head()

행정경계 별로 정보 확인하기

umd_station_info_dict = {}

for umd_key in umd_keys:
    umd_station_info_dict[umd_key] = {}
    umd_station_info_dict[umd_key]['충전소명'] = []
    umd_station_info_dict[umd_key]['급속'] = 0
    umd_station_info_dict[umd_key]['완속'] = 0
    umd_station_info_dict[umd_key]['전체'] = 0
    
    
for i in range(len(charge_st_df)):
    umd = charge_st_df['읍면동 (행정경계)'].iloc[i]
    fast_slow = charge_st_df['급속/완속'].iloc[i]
    
    umd_station_info_dict[umd]['충전소명'].append(charge_st_df['충전소명'].iloc[i])
    
    umd_station_info_dict[umd][fast_slow] += 1
    
    umd_station_info_dict[umd]['전체'] += 1
umd_names = list(umd_station_info_dict.keys())
charge_st_names = []
fast_list = []
slow_list = []
whole_list = []
car_enroll_list = []

for key in umd_names:
    charge_st_name = " | ".join(umd_station_info_dict[key]['충전소명'])
    
    if charge_st_name == '':
        charge_st_name = None
    charge_st_names.append(charge_st_name)
    
    fast_list.append(umd_station_info_dict[key]['급속'])
    slow_list.append(umd_station_info_dict[key]['완속'])
    whole_list.append(umd_station_info_dict[key]['전체'])
    car_enroll_list.append(umd_car_infos[key])
    
umd_infos_df = pd.DataFrame({"읍면동":umd_names, "충전소 목록":charge_st_names, 
                             "급속 충전소/개":fast_list, "완속 충전소/개":slow_list, "전체 충전소/개":whole_list, 
                             "차량등록현황":car_enroll_list})
                             
umd_infos_df

행정경계 인구 현황 데이터 불러와서 합치기

pop_df = pd.read_csv("./data/" + file_list[6])
umd_pop_df = pop_df.groupby('읍면동').sum()
umd_pop_df

new_umd_infos_df = pd.merge(umd_infos_df, umd_pop_df, left_on='읍면동', right_index=True)
new_umd_infos_df

전기차 보급현황 데이터 합치기

bogup_df = pd.read_csv("./data/" + file_list[5])
bogup_df_2017 = bogup_df[bogup_df['기준년도'] == 2017]
indexs = list(bogup_df_2017['행정구역'])
bogup_df_2017 = bogup_df_2017.loc[ : , ['보급현황']]
bogup_df_2017.index = indexs
bogup_df_2017.columns = ['2017 보급현황']
bogup_df_2018 = bogup_df[bogup_df['기준년도'] == 2018]
bogup_df_2018 = bogup_df_2018.loc[ : , ['보급현황']]
bogup_df_2018.index = indexs
bogup_df_2018.columns = ['2018 보급현황']
bogup_df_2019 = bogup_df[bogup_df['기준년도'] == 2019]
bogup_df_2019 = bogup_df_2019.loc[ : , ['보급현황']]
bogup_df_2019.index = indexs
bogup_df_2019.columns = ['2019 보급현황']
bogup_df_2020 = bogup_df[bogup_df['기준년도'] == 2020]
bogup_df_2020 = bogup_df_2020.loc[ : , ['보급현황']]
bogup_df_2020.index = indexs
bogup_df_2020.columns = ['2020 보급현황']
new_umd_infos_df = pd.merge(new_umd_infos_df, bogup_df_2017, left_on='읍면동', right_index=True)
new_umd_infos_df = pd.merge(new_umd_infos_df, bogup_df_2018, left_on='읍면동', right_index=True)
new_umd_infos_df = pd.merge(new_umd_infos_df, bogup_df_2019, left_on='읍면동', right_index=True)
new_umd_infos_df = pd.merge(new_umd_infos_df, bogup_df_2020, left_on='읍면동', right_index=True)
new_umd_infos_df

bogup_df = pd.read_csv("./data/" + file_list[5])
total_bogup_df = bogup_df.groupby("행정구역").sum().loc[:, ['보급현황']]
new_umd_infos_df = pd.merge(new_umd_infos_df, total_bogup_df, left_on='읍면동', right_index=True)
new_umd_infos_df