법정동 -> 행정동 mapping

ewillwin·2022년 7월 19일
1

TSMtech Record

목록 보기
11/39

저번주 이슈 사항

  • 건물에너지 DB 구축 끝난 줄 알았는데 모든 데이터가 법정동 기반이었다는 걸 API 연동 test 하면서 발견함
  • dataset의 법정동코드를 행정동코드로 mapping 해야함

DB 재구축 문제점 및 설계

  • 행정안전부에서 제공하는 데이터로는 법정동코드와 행정동코드가 정확히 1대 1로 매핑이 되지 않음
  • 카카오맵 api의 요청이 하루에 10만개로 제한됨
    -> 이 데이터를 이용하여 법정동코드와 행정동코드가 1대 1 mapping이 되는 것만 모아 mapping table 1을 만듦
    -> mapping table 1로 걸러지지 않는 경우를 mapping table 2로 처리/ mapping table 2는 지번주소와 행정동코드 mapping table/ 2022년 3월 (가장 최근 데이터)의 지번주소를 이용해 카카오맵 api를 통해 행정동코드를 얻음
    -> 2011년 소비량 데이터부터 법정동코드와 행정동코드 mapping 시작/ mapping table 2는 계속해서 update 해주고, table 두 개로도 걸러지지 않는 경우는 어쩔 수 없이 카카오맵 api로 요청을 보내 행정동코드를 얻음

-> 두 개의 mapping table (map1, map2) 완성

import chunk
from typing import final
from venv import create
import pandas as pd
import multiprocessing
import base64
import chunk
import os
import sys
import pymysql
import requests
from sqlalchemy import create_engine
import requests
import warnings
import fileinput
import glob
from multiprocessing import Process

Chunksize = 1000
warnings.simplefilter(action='ignore', category=FutureWarning)
kakao_key=["","","","","","","","",""]

index=0
def get_hangjeongdong(addr): #행정동코드 가져오는 함수
    global index
    global kakao_key
    url = ""
    params={'query':addr}
    headers = {"Authorization":"KakaoAK "+ kakao_key[index]}
    hangjeongdong=requests.get(url,params=params,headers=headers).json()
    if('documents' not in hangjeongdong):  # 일일 api요청 개수가 초과 했을때
        return 100
    hangjeongdong=hangjeongdong['documents']
    if(len(hangjeongdong)==0): # 행정동이 리턴되지 않을때
        return False
    else :
        hangjeongdong=hangjeongdong[0]['address']['h_code']
        if hangjeongdong == '':
            return False
        else:
            return hangjeongdong


map1 = pd.read_excel("C:/Users/TSM/Downloads/map1.xlsx",names=['행정동코드','법정동코드'])
map1 = map1.astype({'행정동코드':'str','법정동코드':'str'})
map2 = pd.read_csv("C:/Users/TSM/Downloads/map2_revised.csv",names=['지번주소','행정동코드','법정동코드'],dtype={'지번주소':'str','행정동코드':'str','법정동코드':'str'},encoding='cp949',low_memory=False)

map1_list = list(map1['법정동코드'])
map2_list = list(map2['지번주소'])


x = 0; y = 0
for chunk in pd.read_csv("C:/Users/TSM/Downloads/gas_final/gas_final.txt",chunksize=Chunksize,sep =',',encoding='cp949',names=['date','addr','bjd','gas'],header=0,low_memory=False):
    chunk=chunk.astype({'date':'str','addr':'str','bjd':'str','gas':'int'})
    for i, row in chunk.iterrows():
        x+=1
        지번주소 = chunk.at[i, 'addr']
        법정동코드 = chunk.at[i, 'bjd']
        if 법정동코드 not in map1_list: # not in map1
            if 지번주소 not in map2_list: # not in map2
                y+=1

                행정동코드 = get_hangjeongdong(지번주소)
                if 행정동코드 == 100:
                    index += 1
                    if index == len(kakao_key):
                        break
                    행정동코드 = get_hangjeongdong(지번주소)
                if 행정동코드 is False:
                    chunk.drop(i,axis=0,inplace=True)
                    continue
                chunk.at[i, 'bjd'] = 행정동코드
                tmp_data = {'지번주소':[지번주소],
                        '행정동코드':[행정동코드],
                        '법정동코드':[법정동코드]}
                tmp_df = pd.DataFrame(tmp_data)
                tmp_df = tmp_df.astype({'지번주소':'str','행정동코드':'str','법정동코드':'str'})
                tmp_df.to_csv('C:/Users/TSM/Downloads/map2_revised.csv',mode='a',index=False,encoding='cp949',header=False)
            else: # exist in map2
                chunk.at[i, 'bjd'] = map2.loc[map2['법정동코드']==법정동코드]['행정동코드'].values.astype('str')[0]
        else: # exist in map1
            chunk.at[i, 'bjd'] = map1.loc[map1['법정동코드']==법정동코드]['행정동코드'].values.astype('str')[0]

    map2 = pd.read_csv("C:/Users/TSM/Downloads/map2_revised.csv",names=['지번주소','행정동코드','법정동코드'],dtype={'지번주소':'str','행정동코드':'str','법정동코드':'str'},encoding='cp949',low_memory=False)
    map2_list = list(map2['지번주소'])
    
    print("읽음: ", x, "    요청 보냄: ", y)
    chunk.to_csv("h_gas.csv", mode='a', index=False, header=None)
    
print("=====================읽음: ", x, "    요청 보냄: ", y, "=====================")
  • 법정동코드 is False 시 행정동코드로 변환되지 않고 법정동코드로 들어감 → 해당 row를 버려야함
  • if문에서 map1_list와 map2_list 안의 "in" 연산을 통해 해당 element의 존재 유무를 찾는 과정에서 오류 발생 → 큰 리스트에서는 다른 연산자 사용해야 할듯
    https://stackoverflow.com/questions/7571635/fastest-way-to-check-if-a-value-exists-in-a-list
  • map2에 행정동코드가 False, 100인 경우에도 값이 들어감 → 다시 처리 필요
  1. 중간에 raw data의 형식에 문제가 생겨 raw data를 다시 구축하느라 작업에 지연이 생김
  2. mapping table1과 mapping table2로도 걸러지지 않는 경우가 생각보다 많아서 그럴 경우 카카오맵 api로 요청을 보내야하기 때문에 코드를 돌리는데 시간이 오래 걸림
profile
Software Engineer @ LG Electronics

0개의 댓글