관리 메뉴

JIE0025

[csv → json] 지도 기능을 위한 법정동 데이터 전처리 (with Jupyter notebook) 본문

백엔드/API, 설계, 데이터 전처리

[csv → json] 지도 기능을 위한 법정동 데이터 전처리 (with Jupyter notebook)

Kangjieun11 2023. 4. 16. 02:22
728x90

 

 

 

 

 애견 소셜네트워크 서비스 마이버디 (MY BUDDY)

https://my-buddy.co.kr/

 

 

 

 

 

 

✅  개요

 

특정 지역을 검색했을때 많이 태그된 게시물을 장소 추천해주는 기능이 기획되었다.

이때 특정 지역의 범위를 얼만큼 할건지, 필터링 기준 단위는 어떻게 할건지에 대한 고민이 있었다.

 

아이디어가 기획만 되고, 구체화되지 않은 상황에서 

데이터 전처리가 필요하다는것은 명확했다.

 

 

✅  준비

가장 먼저 팀원분이 전국 시군구 데이터가 있는 csv파일을 찾아주셨다. 

 

국토교통부_전국 법정동 20221031 .csv파일을 확인해보니 

시도명 / 시군구명으로 분리되어있음을 확인했다.

 

서비스가 전국구를 필터링 할 수 있게 제공할 것이었기때문에

읍면동이나, 리까지 선택하는건 과하다고 판단했다.

 

따라서 시도명과, 시군구명까지만 필터링을 하자

 

"서울 강남구 테헤란로 ~~~~" 이렇게 있다 가정했을때

<서울 강남구>까지 검색의 범위에 넣자고 결정되었다.

 

 

✅  데이터 전처리 진행

 

데이터 전처리를 위해 다음과 같은 과정이 필요했다. 

 

1. python으로 .csv파일 읽어오기

 

2. 읽어들인 파일에서 "시도명", "시군구명" 을 가져오기

2-1) 중복은 제거한다.

 

3. 데이터는 어떻게 제공할것인지 고민하기

 

 

 

⏺ 데이터 형식 선택 : JSON 

WHY JSON ?

만약 이 데이터가 DB에 저장되고 프론트가 지속적으로 요청을 하는것은 비효율적일것이라고 생각했다.

(전국 시군구 데이터는 변경될 가능성이 거의 없는 데이터이기 때문이다)

 

따라서 프론트 작업 디렉터리에 저장해놓고 갖다 쓰는게 더 효율적이라 판단했다.

 

이는 프론트분들이 사용하기 쉬운 형식으로 가공해야함을 의미했고,
CSR방식으로 서버와 클라이언트간 소통을 JSON형식을 통했었기 때문에

 

해당 데이터도 JSON 형식으로 만들면 되겠다고 결론이 났다.

 

 

 

🖥 코드

먼저 파일 이름을 state-region.csv로 변경했다.

 

import csv
import json
 
csv_file_path = 'state-region.csv' 
 
state_region_list = []
with open(csv_file_path, 'r', newline='', encoding='cp949') as file:
    reader = csv.DictReader(file)

    for row in reader:
        state = row['시도명']
        region = row['시군구명']

        if (state, region) not in state_region_list:
            state_region_list.append((state, region))

    
sorted_list = sorted(state_region_list, key= lambda x : (x[0], x[1]))
     
     
#Json으로 만들기
data = []
for state, region in state_region_list:
    data.append({'state': state, 'region': region})

json_data = json.dumps(data, ensure_ascii=False)

print(json_data)

 

✍️  csv_file_path 

파일을 가져오기 위한 변수, 현재 수정중인 .ipynb파일과 동일한 디렉터리에 .csv파일이 존재했다.

 

✍️   state_region_list 

데이터를 어떻게 저장해야할지 고민하다가 단순 리스트를 사용하게 되었는데

 

1) dictionary key-value를 사용할까 고민을 했었다.

딕셔너리를 썼을 때의 장점을 Key가 유일하기 때문에 데이터가 존재하는지 여부를 O(1)안에 찾을 수 있기 떄문이다.

state, region 데이터의 중복을 없애기 위해서는 데이터가 존재하는지를 확인해줘야했다.

 

그러나 개발 당시에는 DIctionary를 사용하지 않았는데 이유는 key값으로 어떤 데이터를 넣는다고 가정했을때 겹치는 데이터가 있어서였다.

 

만약 강원도 삼척시에서 

<강원도>를 key로 넣는다면? 너무 많은 시군구 데이터가 존재해서 당연히 넣을 수 없었고,

 

그렇다고 시군구데이터를 key로 넣는다면?

<중구>만 하더라도 서울, 인천, 대전, 부산, 울산, 대구에 존재한다는 사실을 알게되었다.

 

무난하게 리스트에 넣고, 처리하자는 생각으로 리스트에 넣었으나....

 

++ 🔥   state_region_dict로 만들라면 만들수 있다.

 

지금 게시글을 작성하는 시점에 떠올랐다.

 

중복을 제거했을때 400~500개의 데이터가 나오는데,

이를 중복 확인하면서 리스트로 처리하면 쓸데없는 연산이 생길 수 있다. 

 

해당 코드가 지속적으로 사용되지 않기 때문에 효율성을 따질 필요는 없지만..

개선해보면 역시 Dictionary를 사용하면 될것이다.

 

먼저 key값으로 서울*광진구 이런식으로 데이터를 추가해주면 된다.

다음 value에는 ["서울", "광진구"]를 넣어준다.

 

이렇게 하면, 데이터 존재여부를 O(1)안에 처리할 수 있고, 

추후 value에서 인덱스로 접근하여, JSON데이터를 만들수 있을 것이다!

 

 

✍️ 파일 처리

with open(csv_file_path, 'r', newline='', encoding='cp949') as file:
    reader = csv.DictReader(file)

    for row in reader:
        state = row['시도명']
        region = row['시군구명']

        if (state, region) not in state_region_list:
            state_region_list.append((state, region))

 

1) with문

https://peps.python.org/pep-0343/

 

PEP 343 – The “with” Statement | peps.python.org

PEP 340, Anonymous Block Statements, combined many powerful ideas: using generators as block templates, adding exception handling and finalization to generators, and more. Besides praise it received a lot of opposition from people who didn’t like the fac

peps.python.org

 

 

 

파일은 open되면 언제나 close되어야하는데, with을 사용하면 파일을 열고 닫는 과정에서 자원을 자동으로 관리된다. 

즉 작업이 끝났을때 파일이 자동적으로 닫힌다는 이야기이다.

 

또 파일을 열고 닫을때 발생하는 예외가 처리된다고 한다. 

 

 

파일 입출력시 예외처리나 닫는것을 코드로 작성하기 위해 try, exception, finally와 같은 블록을 사용하지 않아도 된다는게 강점이다!

 

2) csv.Dictreader()

 

https://docs.python.org/ko/3/library/csv.html

 

{'first_name': 'John', 'last_name': 'Cleese'}

 

이 코드를 사용하면, 데이터를 딕셔너리처럼 가져온다.

 

 

csv — CSV File Reading and Writing

Source code: Lib/csv.py The so-called CSV (Comma Separated Values) format is the most common import and export format for spreadsheets and databases. CSV format was used for many years prior to att...

docs.python.org

 

 

for row in reader:
        state = row['시도명']
        region = row['시군구명']

        if (state, region) not in state_region_list:
            state_region_list.append((state, region))

 

reader를 통해 row를 가져오는데, 열의 이름을 지정해주어서 데이터를 각각 state, region에 할당했다.

이후 해당 데이터가 state_region_list에 존재하지 않으면, 데이터를 추가해주며 중복을 제거했다.

 

 

 

3) 데이터 정렬

 

파이썬에서 데이터를 정렬하는 방법은 아주 간단하다.

key=lambda를 통해 기준을 만들어주면된다.

 

리스트에 state, region 순서로 데이터가 들어갔기 때문에,

시도명 / 시군구명 순으로 한글 오름차순 정렬을 시켜주었다.

 

sorted_list = sorted(state_region_list, key= lambda x : (x[0], x[1]))

 

 

✍️ 1차 출력

#출력테스트
for state, region in sorted_list:
    print(state, region)

 

출력을 하면 다음과 같이 데이터가 정상적으로 나온다. 이 데이터를 JSON으로 만들어보자.


 

 

 

✍️ JSON으로 만들기

data = []
for state, region in state_region_list:
    data.append({'state': state, 'region': region})

json_data = json.dumps(data, ensure_ascii=False)

print(json_data)

 

https://tempdev.tistory.com/24

 

python에서 json 다루기

파이썬에서 json을 다루어 보자. 모듈을 사용하지 않는 방법도 있지만, 편하게 하기 위해 json모듈을 import 하여 사용하자. import json json모듈은 json형식의 문자열들을 파이썬 객체로 바꾸어주고, 그

tempdev.tistory.com

 

 

data를 일단 리스트로 정의하고, 

json형식에 맞게 만들어서 리스트에 추가했다.

 

이후 json으로 만들기 위해 dumps 메서드를 사용했다.

 

✔️한글 깨짐 이슈 해결

https://frhyme.github.io/python-libs/py_json_dump_korean/

 

python에서 json을 “한글을 읽을수 있게” 저장하는 방법

JSON: JavaScript Object Notation

frhyme.github.io

 

 

😉 2차 출력

 

이렇게 파일을 생성해서 프론트엔드 개발자 분께 전달했다.

 

 

 

 

✅  데이터 오류

 

데이터가 너무 많아서 미처 살피지 못한 오류가 하나 발생했고, 

직접 데이터를 사용하시던 프론트엔드 개발자가 찾아주셨다.

 

 

바로 아래와 같은 데이터 형식이 들어있었던것...

 

 

 

 

사실 시군구명이기 때문에 저렇게 들어있는게 맞긴 하다.

 

결과적으로  .csv파일을 잘못 긁어온게 아닌,

너무 많은데이터가 있어서 구체적으로 살피지 못해서 발생한 문제였고

 

데이터 자체의 문제였기 때문에 프론트엔드 개발자분이 직접 수정을 해주셨다.

 

 

 

 

오늘은 전처리에만 집중한 게시글을 적어봤다.



다음은  우리 서비스의 데이터를 설계하며

  • KAKAO MAPS API와  우리 데이터를 매핑한 과정,
  • 전처리된 JSON 데이터를 한번더 가공하는 과정을 게시글로 작성해야겠다.

 

 

 

 

✔️ KAKAO MAPS API와  우리 데이터를 매핑한 과정 보러가기

https://jie0025.tistory.com/505

 

[API] 장소 등록에서, KAKAO-MAPS와 매핑한 API 설계

✅  개요 지도 API 를 사용하기로 결정되면서 장소에 대한 데이터를 우리 서비스에 저장해둘 필요가 생겼다. 프론트 분과 상의 후 KAKAO MAPS API를 사용하기로 되었고, KAKAO MAPS API의 데이터에서 어

jie0025.tistory.com